iOS 面试题(一)

● OC语言特点:继承、多态、封装
1、是面向对象的设计语言
2、仅支持单一父类继承,不支持多重继承

跳出面向对象思想()多态
      多态:不同对象以自己的方式响应相同的消息的能力叫做多态。 (自我理解:不同的类可以有相同的属性、方法)
跳出面向对象思想()继承

继承是罪恶,尽量不要继承。(避免:拔出萝卜带出泥)就我目前了解到的情况看,除了安居客的Pad App没有在框架级针对UIViewController有继承的设计以外,其它公司或多或少都针对UIViewController有继承,包括安居客iPhone app(那时候我已经对此无能为力,可见View的架构在一开始就设计好有多么重要)。甚至有的还对UITableView有继承,这是一件多么令人发指,多么惨绝人寰,多么丧心病狂的事情啊。虽然不可避免的是有些情况我们不得不从苹果原生对象中继承,比如UITableViewCell但我还是建议尽量不要通过继承的方案来给原生对象添加功能,前面提到的Aspect方案和Category方案都可以使用。Aspectload来实现重载函数,用Category来实现添加函数,当然,耍点手段用Category来添加property也是没问题的。这些方案已经覆盖了继承的全部功能,而且非常好维护,对于业务方也更加透明,何乐而不为呢。
不用继承可能在思路上不会那么直观,但是对于不使用继承带来的好处是足够顶得上使用继承的坏处的。顺便在此我要给
Category正一下名:业界对于Category的态度比较暧昧,在多种场合(讲座、资料文档)都宣扬过尽可能不要使用Category。它们说的都有一定道理,但我认为Category是苹果提供的最好的使用集合代替继承的方案,但针对Category的设计对架构师的要求也很高,请合理使用。而且苹果也在很多场合使用Category,来把一个原本可能很大的对象,根据不同场景拆分成不同的Category,从而提高可维护性。
不使用继承的好处我在这里已经说了,放到iOS应用架构来看,还能再多额外两个好处:1.在业务方做业务开发或者做Demo时,可以脱离App环境,或花更少的时间搭建环境。2.对业务方来说功能更加透明,也符合业务方在开发时的第一直觉。



OC、C的区别 C是 面向过程的设计语言

OC、C++的区别 都是 面向对象的设计语言,
1、继承: OC不支持多重继承,而C++语言支持多重继承(多重继承的效率不高)
2、函数调用:OC通过 互相传递消息实现函数调用,而C++直接进行函数调用
3、接口:OC采用protocol协议(非正式和正式)的形式来定义接口,而C++采用虚函数的形式来定义接口。


Object-C的优点、缺点  
objc
优点:  
  1) Cateogies 
  2) Posing 
  3)
动态识别  
  4)
指标计算  
  5
)弹性讯息传递  
  6)
不是一个过度复杂的 C 衍生语言  
  7) Objective-C
C++ 可混合编程  
缺点
  1) 
不支援命名空间  
  2)  
不支持运算符重载  
  3
)不支持多重继承  
  4
)使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到。(如内联函数等),性能低劣。  
多重继承:指的是一个类可以同时继承多个父类的行为和特征功能。



copy retain : retain 相当于 strong
1
copy其实是建立了一个相同的对象,而retain不是;
2
copy是内容拷贝,retain是指针拷贝;  
3
copy是内容的拷贝,对于像NSString,的确是这样,但是如果copy的是一个NSArray?这时只是copy了指向array中相对应元素的指针.这便是所谓的"浅复制".
4
copy的情况:NSString *newPt = [pt copy];
此时会在堆上重新开辟一段内存存放@"abc"比如0X1122内容为@"abc同时会在栈上为newPt分配空间比如地址:0Xaacc内容为0X1122因此retainCount增加1newPt来管理0X1122
这段内存;

assign retain
1
assign:简单赋值,不更改索引计数;
2
assign的情况:NSString *newPt = [pt assing]; 
此时newPtpt完全相同地址都是0Xaaaa内容为0X1111newPt只是pt的别名,对任何一个操作就等于对另一个操作,因此retainCount不需要增加;
3
assign就是直接赋值;
4
retain使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收;    
5
retain的情况:NSString *newPt = [pt retain]; 
此时newPt的地址不再为0Xaaaa,可能为0Xaabb但是内容依然为0X1111因此newPtpt都可以管理"abc"所在的内存,因此retainCount需要增加

readonly
属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器。或者如果你使用@synthesize关键字,也是有读取器方法被解析   
readwrite
说明属性会被当成读写的,这也是默认属性。设置器和读取器都需要在@implementation中实现。如果使用@synthesize关键字,读取器和设置器都会被解析;

1.atomic nonatomic
atomic 默认是有该属性的,这个属性是为了保证程序在多线程情况,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题。
nonatomic 如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率。

不保证setter/getter的原子性,多线程情况下数据可能会有问题。nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。

先释放原先变量,再将新变量  retain然后赋值;



weak and strong  (强引用和弱引用的区别)
1
 weakstrong属性只有在你打开ARC时才会被要求使用,这时你是不能使用retain release autorelease操作的,因为ARC会自动为你做好这些操作,但是你需要在对象属性上使用weakstrong,其中strong就相当于retain属性,而weak相当于assign
2
、只有一种情况你需要使用weak(默认是strong),就是为了避免retain cycles(就是父类中含有子类{父类retain了子类},子类中又调用了父类{子类又retain了父类},这样都无法release    
3
、声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。   

strong,weak,copy具体用法:
1.
具体一点:IBOutlet可以为weakNSStringcopyDelegate一般为weak,其他的看情况。
一般来说,
内部的属性设置为strong,类外部的属性设置为weak说到底就是一个归属权的问题。小心出现循环引用导致内存无法释放。
2.
不用ARC的话就会看到很多retian
3.
如果你写了@synthesize abc = _abc;的话,系统自动帮你声明了一个_abc的实例变量。
  
使用assign:对基础数据类型NSInteger)和C数据类型(int, float, double, char,等)
  
使用copyNSString
  使用retain对其他NSObject和其子类 


 ARC(Automatic Reference Counting):
就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。
该机能在iOS 5/ Mac OS X 10.7开始导入,利用Xcode4.2以后可以使用该特性。

property
简短的代码更易读: _property 的写法比 self.property 更短,也更简单。我认为这样写出来的代码更方便阅读。
执行速度更快,IPA体积更小
我之前从来没想到过这两者之间的速度和应用体积会有很大差别。不过一个同行(来自国外著名的社交网络公司)告诉我,他们公司发现二者还是有不小的差距,如果你们的应用需要做一些深度优化,可以考虑一下把 self.property 换成 _property 。但我觉得,大部分应用都应该是不需要做这种深度优化的。
循环引用问题
微博上的@王_晓磊在评论中提到:直接用私有变量有个需要特别注意的地方,在 block 里直接写 _property 相当于 self->_property ,虽然没写 self,但是暗含了对 self 的retain,容易造成循环引用。要记得用 weakSelf/strongSelf 大法。


浅复制和深复制的区别?shallow copy and deep copy
答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身。
  深层复制:复制引用对象本身。
用网上一哥们通俗的话将就是:
浅复制好比你和你的影子,你完蛋,你的影子也完蛋
深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。

__block __weak的区别理解

1.__block对象在block中是可以被修改、重新赋值的。 
2.__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。

使用了__weak修饰符的对象,作用等同于定义为weakproperty。自然不会导致循环引用问题,因为苹果文档已经说的很清楚,当原对象没有任何强引用的时候,弱引用指针也会被设置为nil

因此,__block__weak修饰符的区别其实是挺明显的: 
1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。 
2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。 
3.__block对象可以在block中被重新赋值,__weak不可以。 
PS__unsafe_unretained修饰符可以被视为iOS SDK 4.3以前版本的__weak的替代品,不过不会被自动置空为nil。所以尽可能不要使用这个修饰符。


iOS 进程、线程 及 堆、栈关系的总结
简而言之,一个程序至少有一个进程,一个进程至少有一个线程. 
多线程
线程是可执行代码的可分派单元。这个名称来源于 执行的线索 的概念。在基于线程的多任务的环境中,所有进程有至少一个线程,但是它们可以具有多个任务。这意味着单个程序可以并发执行两个或者多个任务。

简而言之,线程就是把一个进程分为很多片,每一片都可以是一个独立的流程。这已经明显不同于多进程了,进程是一个拷贝的流程,而线程只是把一条河流截成很多条小溪。它没有拷贝这些额外的开销,但是仅仅是现存的一条河流,就被多线程技术几乎无开销地转成很多条小流程,它的伟大就在于它少之又少的系统开销。(当然伟大的后面又引发了重入性等种种问题,这个后面慢慢比较)。


 堆和栈的区别 
管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak 
申请大小: 
栈:Windows,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。 
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。 
碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。
        对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间
        弹出
 
分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。 
分配效率: 栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是 C/C++ 函数库提供的,它的机制是很复杂的。
堆和栈的区别
一、预备知识—程序的内存分配
一个由 c/C++ 编译的程序占用的内存分为以下几个部分:
1、栈区(stack由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2 、堆区( heap 一般由程序员分配释放,若程序员不释放,程序结束时可能由 OS 回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3 、全局区(静态区)( static ,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。  -  程序结束后由系统释放。
4 、文字常量区: 常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区:存放函数体的二进制代码。
堆和栈上的指针  
指针所指向的这块内存是在哪里分配的 , 在堆上称为堆上的指针 , 在栈上为栈上的指针
在堆上的指针 , 可以保存在全局数据结构中 , 供不同函数使用访问同一块内存
在栈上的指针 , 在函数退出后 , 该内存即不可访问
什么是指针的释放
具体来说包括两个概念
1
释放该指针指向的内存 , 只有堆上的内存才需要我们手工释放 , 栈上不需要
2
将该指针重定向为 NULL. 
数据结构中的指针
其实就是指向一块内存的地址 , 通过指针传递 , 可实现复杂的内存访问
函数指针
指向一块函数的入口地址
指针作为函数的参数
比如指向一个复杂数据结构的指针作为函数变量  
这种方法避免整个复杂数据类型内存的压栈出栈操作 , 提高效率
注意 : 指针本身不可变 , 但指针指向的数据结构可以改变
指向指针的指针
指针指向的变量是一个指针,即具体内容为一个指针的值,是一个地址
此时指针指向的变量长度也是4
指针与地址的区别
1
指针意味着已经有一个指针变量存在,他的值是一个地址,指针变量本身也存放在一个长度为四个字节的地址当中,而地址概念本身并不代表有任何变量存在
2
指针的值,如果没有限制,通常是可以变化的,也可以指向另外一个地址
  
地址表示内存空间的一个位置点,他是用来赋给指针的,地址本身是没有大小概念,指针指向变量的大小,取决于地址后面存放的变量类型
指针与数组名的关系
  其值都是一个地址,但前者是可以移动的,后者是不可变的
怎样防止指针的越界使用问题
  必须让指针指向一个有效的内存地址
1
防止数组越界 
2
防止向一块内存中拷贝过多的内容 
3
防止使用空指针 
4
防止改变const修改的指针 
5
防止改变指向静态存储区的内容 
6
防止两次释放一个指针 
7
防止使用野指针

全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
           全局变量储存在静态数据库,
 局部变量在堆栈。
堆栈溢出一般是由什么原因导致的?
没有回收垃圾资源
什么函数不能声明为虚函数?
            constructor
什么是平衡二叉树?
           
左右子树都是平衡二叉树且左右子树的深度差值的绝对值不大于1

static 关键字的作用: 
1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次, 
因此其值在下次调用时仍维持上次的值; 
2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问; 
3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内; 
4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝; 
5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。  


conststaticexterndefine简介

常量const修饰的变量是不可变的之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量。

实例变量(属于成员变量中的一大类): 在类中定义的实例变量,是可以在各个方法内使用的。

局部变量 是在方法内作定义说明的。其作用域仅限于方法内。(随时随处可定义局部变量)

静态变量 static修饰的变量,是一个私有的全局变量。函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值; 

1、节省内存。静态变量只存储一处,但供所有对象使用。
2、它的值是可以更新的。
3、可提高时间效率。只要某个对象对静态变量更新一次,所有的对象都能访问更新后的值。

全局变量extern
  也称之为外部变量,是在方法外部定义的变量。它不属于哪个方法,而是属于整个源程序。 作用域是整个源程序。
  如果全局便利和局部变量重名,则在局部变量作用域内,全局变量被屏蔽,不起作用。
宏define:既能定义变量,又能定义函数
auto: auto 定义一个相同的变量,但是在函数内,对外部的变量没有影响。

2. 执行时刻:宏是预编译(编译之前处理),const是编译阶段。

3. 编译检查:宏不做检查,不会报编译错误,只是替换,const会编译检查,会报编译错误。

4. 宏的好处:宏能定义一些函数,方法。 const不能。

5. 宏的坏处:使用大量宏,容易造成编译时间久,每次都需要重新替换。

注意:很多Blog都说使用宏,会消耗很多内存,我这验证并不会生成很多内存,宏定义的是常量,常量都放在常量区,只会生成一份内存。



响应者链 响应者链详解

响应者链条是由多个响应者对象连接起来的链条,其中响应者对象是能处理事件的对象,所有的ViewViewController都是响应者对象,利用响应者链条能让多个控件处理同一个触摸事件.

事件响应链。包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播.可以说点事件的分发,传递以及处理。具体可以去看下touch事件这块。

简单的说,  iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。这种有响应和处理事件的对象,我们称之为响应者对象

UIApplicationUIViewControllerUIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件

 响应者链的事件传递机制:

如果当前view不能处理当前事件,那么事件将会沿着响应者链(Responder Chain)进行传递,直到遇到能处理该事件的响应者(Responsder Object)

响应者链的事件传递过程。

1)如果view的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父视图

2)在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理

3)如果window对象也不处理,则其将事件或消息传递给UIApplication对象

4)如果UIApplication也不能处理该事件或消息,则将其丢弃

3种类型的block
根据 isa 指针, block 一共有 3 种类型的 block
_NSConcreteGlobalBlock 全局静态
_NSConcreteStackBlock 保存在栈中,出函数作用域就销毁
_NSConcreteMallocBlock 保存在堆中, retainCount == 0 销毁

viewframebounds之区别(位置和大小)
frame: 该view在父view坐标系统中的位置和大小。(参照点是,父亲的坐标系统)
bounds:该view在本地坐标系统中的位置和大小。(参照点是,本地坐标系统,就相当于ViewB自己的坐标系统,以0,0点为起点)
center:该view的中心点在父view坐标系统中的位置和大小。(参照电是,父亲的坐标系统)

单例类:Singleton
单例 模式确 保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
1.
单例模式的要点:要点有三个
一是: 某个类只能有一个实例;
二是: 它必须自行创建这个实例;
三是: 它必须自行向整个系统提供这个实例。


2.单例模式的优点:
    1. 实例控制: Singleton  会阻止其他对象实例化其自己的  Singleton  对象的副本,从而确保所有对象都访问唯一实例。
2. 灵活性:因为类控制了实例化过程,所以类可以更加 灵活修改 实例化过程
 
IOS
中的单例模式
  在 oc 中要实现一个单例类,至少需要做以下四个步骤:
    1 、为 单例对象创建 一个 静态实例, 并初始化,然后设置成 nil
   2 、实现一个 例构造方法 ,检查声明的静态实例是否为 nil ,如果是则新建,并返回一个本类的实例,
   3 、重写  allocWithZone 方法,用来 保证其他人 直接使用 alloc init 试图获得 一个新实 的时候不产生一个新实例,
4 、适当实现  allocWithZone copyWithZone release autorelease                                                                                                         
+ ( Singleton *)singleton
{
     static  Singleton *instance =  nil;
     static  dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
        instance = [[ self  allocinit];
    });
     return instance;
}
官方推荐:
//1. Apple 官方推荐的单例写法,这种能够保证多线程的情况下只有一个对象
//2. dispatch_once    这个 block 中得方法,只会执行一次


工厂方法模式
 /**
  *  如何理解三种设计模式:简单工厂工厂方法抽象工厂
 1 、简述
首先需要说明一下,简单工厂模式不属于 23 GOF 设计模式之一。它也称作静态工作方法模式,是工厂方法模式的特殊实现(也就是说工厂模式包含简单工厂模式)。这里对简单工厂模式进行介绍,是为后面的工厂方法和抽象工厂模式做一个引子。
 2 、定义
专门定义一个类来负责创建其他类的实例,被创建的实例通常具有共同的父类。
实际上就是由一个工厂类,根据传入的参数,动态地决定创建出哪一个产品类的实例。

GOF
是这样描述工厂模式的:在基类中定义创建对象的一个接口,让子类决定实例化哪个类。工厂方法让一个类的实例化延迟到子类中进行。
        
工厂方法要解决的问题是对象的创建时机,它提供了一种扩展的策略,很好地符合了开放封闭原则。
工厂方法也叫做虚构造器( Virtual Constructor).
 */




你平时自定义过那些视图控件
UITapBarController、UItableViewCell、UIview、Button
因为系统的一些控件不能满足项目的需求,这时需要我们自定义控件

SVN
代码版本控制器,方便管理代码(通过时间判定来不断 保存每个时间段里被修改的代码,可用于帮助 2-3 人整合代码,集中式),分布式用到git,现在的Xcode支持gitup功能


GCD
苹果公司的开发技术。推荐使用。
线程几种方式   NSThread  NSOperation  GCD好处与工作原理
1. Thread :是三种方法里面相对轻量级的,但需要管理线程的生命周期、同步、加锁问题,这会导致一定的性能开销

2. Cocoa Operations:是基于OC实现的,NSOperation以面向对象的方式封装了需要执行的操作,不必关心线程管理、同步等问题。NSOperation是一个抽象基类,iOS提供了两种默认实现:NSInvocationOperation和NSBlockOperation,当然也可以自定义NSOperation

3. Grand Central Dispatch(简称GCD,iOS4才开始支持):提供了一些新特性、运行库来支持多核并行编程,它的关注点更高:如何在多个cpu上提升效率

GCD
1.用于解决 多核并行运算的问题,可以 平行操作更多的任务,会自动管理线程的生存周期
2.它们都允许程序 将任务切分为多个单一任务然后提交至工作队列来 并发 地或者 串行 地执行 ,GCD比之NSOpertionQueue更底层更高效
3.工作原理:让程序平行排队的任务, 在任何可用的处理器核心上执行任务。
一个任务可以是一个 函数(function)或者是一个 block。 
4.GCD的 底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。
GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行.
 
使用GCD的好处和注意事项:
1.通过使用GCD可以高效的利用处理器多核运算的能力
2.繁杂耗时较长的计算任务可以通过GCD 分配给其他线程来完成任务.
3.如果没有特殊需求,不应引入线程增加程序复杂度
4.谨慎对待线程阻塞.
 
理解Dispatch Queue(调度列队):
Dispatch Queue分为下面三种:
1. 串行队列Serial Queue   它们 各自是同步执行的(一般很少用到)

2. 并行队列: dispatch   global queue,可以并发地执行多个任务,但是执行 成的顺序是随机的

3. 主队列 Main queue它是全局可用的serial queue,它是在应用程序 主线程上执行任务的。UI层面的更新都必须通过主线程来执行,否则会出现很多无法预估的问题.
 
什么时候创建多线程:当主线程中有比 较大的耗时的任务时,该任务 会阻塞主线程,这时就可以开辟一条新线程。
  // 从其他线程回到主线程的方法
    // NSThread
    [ self performSelectorOnMainThread: @selector(run) withObject: nil waitUntilDone: NO];
    // GCD
    dispatch_async( dispatch_get_main_queue(), ^{
    });
   
    // NSOperationQueue
    [[ NSOperationQueue mainQueue] addOperationWithBlock:^{
    }];


MVC
MVC设计模式考虑三种对象:模型对象、视图对象和控制器对象。Modal、View、Controller
模型对象:负责保有应用程序的数据和定义操作数据的逻辑。                  --->处理数据
视图对象:知道如何显示应用程序的模型数据,而且可能允许用户对其进行编辑。 --->显示数据、用户编辑数据
控制器对象:是应用程序的视图对象和模型对象之间的协调者。                ---> 模型和视图的协调着
特性: 
1.提高代码的复用性
2.结构清晰便于维护
3.在低内存可用的设备上,由于modal和view的分离,便于节省内存开销
 
模态视图 已经淘汰了,但是为了满足项目的需求
我平时只使用过模态视图,来处理一个简单的视图,比如弹出:详情页面、选照片页面等


KVC
全称是Key-value coding 键值编码 使用字符串来标识属性,是间接访问对象的属性, 而不是通过调用存取方法。
特点:  可以简化程序代码
 
KVO
全称Key-value observing, 键值观察。提供了一种当 其它对象属性被修改时 通知当前对象的机制。在MVC大行其道的Cocoa中,KVO机制很适合实现model和controller类之间的通讯。
特点:他提供了观察某一属性变化的方法,极大的简化了代码。,比方说根据A(数据类)的某个属性值变化,B(view类)中的某个属性做出相应变化。对于推崇MVC的cocoa而言,kvo应用的地方非常广泛。(这样的机制听起来类似Notification,但是notification是需要一个发送notification的对象,一般是notificationCenter,来通知观察者。而kvo是直接通知到观察对象。
1 注册:
-(void)addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context
keyPath就是要观察的属性值,options给你观察键值变化的选择,而context方便传输你需要的数据(注意这是一个void型)
2 实现变化方法:
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object  change:(NSDictionary *)change context:(void *)context
change里存储了一些变化的数据,比如变化前的数据,变化后的数据;如果注册时context不为空,这里context就能接收到。
 
 
BLOCK
可以说是一个 代码段 ,可以 实现指定的功能 指向一段代码的 内存地址
1.能够读取 其它函数内部的变量。
2.相当于简单地 实现了代理
3. block配合上 dispatch_queue可以方便地实现简单的 多线程编程 异步编程,一个block实际是一个对象
4.创建、描述 功能 、调用


作为方法的参数(method parameter)
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
作为方法参数的时候被调用
[someObject someMethodThatTakesABlock: ^ returnType  ( parameters ) {...}];


Notification
消息的 发送者 告知 接收者事件已经发生或者将要发送,仅此而已, 接收者 不能影响: 发送者的行为。
 

Delegate
代理的目的是 改变或传递控制链。可以 减少框架复杂度
消息的发送者(sender)告知接收者(receiver)某个事件将要发生,delegate 同意,然后发送者响应事件
发送者 委托  接收者 去做莫件事
delegate机制使得接收者可以改变发送者的行为。
通常发送者和接收者的关系是直接的  一对多 的关系。
 
什么时候用Delegate,什么时候用Notification?
答: D elegate:针对     一对一  的关系,并且reciever 可以返回值 给sender
Notification:可以针对 一对一/多/无    ,reciever 无法返回值给 sender.所以,delegate用于sender希望接受到 reciever的某个功能反馈值,notification用于通知多个object某个事件。
 


自动释放池是什么,如何工作
       当您向一个对象发送一个autorelease消息时,Cocoa就会将该对象的一个引用放入到最新的自动释放池。它仍然是个正当的对象,因此自动释放池定义的作用域内的其它对象可以向它发送消息。当程序执行到作用域结束的位置时,自动释放池就会被释放,池中的所有对象也就被释放。 
1.  OC是通过一种" retainCount"(引用计数)的方式来管理内存的,
 对象在开始 分配内存 (alloc)的时候引用计数为一,以后每当碰到有 copy,retain的时候引用计数都会加一, 
每当碰到 release和autorelease的时候引用计数就会减一,如果此对象的计数变为了0, 就会被系统销毁. 
2. NSAutoreleasePool 就是用来做引用计数的管理工作的,这个东西一般不用你管的. 
3. autorelease和release没什么区别,只是 引用计数减一的时机不同而已,autorelease会在对象的使用真正结束的时候才做引用计数减一. 


Socket  提供了网络通信的能力
     套接字提供一套可用的用户接口。实质并不是一种协议,没有规定计算机应当怎么样传递消息,只是给程序员提供了一个发送消息的接口,程序员使用这个接口提供的方法,发送与接受消息。可以和服务器处于长时间连接状态,等待过程中发送包
Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。
对TCP/IP进行封装,方便用户使用,及时交互,一旦连接就一直通信。每隔一段时间发送一个心跳包检测。
1)Socket 是一个针对TCP和UDP编程的接口,你可以借助它建立TCP 连接等等。而TCP和UDP协议属于传输层 。
  而http是个应用层的协议,它实际上也建立在TCP协议之上。 
 (HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。)
 2)Socket是对TCP/IP协议的封装,是一个调用接口(API),通过Socket,我们才能使用TCP/IP 协议

IP 网络层
相当于导航
关于TCP和IP:IP是网络层的协议,TCP是传输层的协议。 它们一起把封装好的数据发送到想要传送到的地址,TCP好比一个司机,IP来导航;
TCP 传输层
传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。一个TCP连接必须要经过三次“对话”才能建立起来。
HTTP 应用层
          超文本传送协议  定义了浏览器(即万维网客户进程)怎样 向万维网服务器请求万维网文档 ,以及服务器怎样把文档传送给浏览器。从层次的角度看,HTTP是面向(transaction-oriented) 应用层协议 ,它是万维网上能够可靠地交换文件(包括文本、声音、图像等各种多媒体文件)的重要基础。
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式, 适用于分布式超媒体信息系统
相应的还有FTP应用层,以前用以局域网内使用,现在很少使用;TELNET用以发送邮件
  UDP: 传输层     非面向对象连接
     只管发送,不管接受。优点是效率高(用在即时通讯,如qq),缺点:易丢包)
用户数据包协议 ,在 网络 中它与 TCP 协议一样用于处理数据包,是一种无连接的协议。在 OSI 模型中,在第四层—— 传输层 ,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在 计算机 之间传输数据的网络应用。包括 网络视频会议 系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。
UDP协议的主要作用是:  网络数据流量压缩成数据包 的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。

  TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,我们来看看这三次对话的简单过程:
1.主机A向主机B发出连接请求数据包;
2.主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包;
3.主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。


HTTP协议建立连接、通讯与关闭连接全过程

为解决服务器TimeWait多的问题,了解了一下TCP/IP协议的连接过程。
以访问一静态页面为例,从建立连接到访问拿到数据,然后关闭的整个过程。

建立连接:
1. 发起请求的一方,从发送syn(递交名片)包开始第一次握手。
2. 收到请求的一方立马回应ack包,发现这是新建连接,然后也给出自己的syn包(递交名片)。(严重来讲,任何一方收到对方数据之后都会回应一个ack表示自己已收到)
3. 发起方收到响应后回应一个ack包。(整个过程注意sequence number的变化)
4. OK。建立互信,可以开始交往!

开始通讯:
1. 客户端(发起方)向服务端(应答方)发起Http请求,如图中Packet 4 :C=GET URI=/higkoo。
2. 服务端收到请求后立马回应了ack,并告诉客户保持连接等待传输数据。
3. 紧接着服务端就向客户端返回了Http响应数据。
4. OK,通讯完成!

关闭连接:
1. 此时,到了图中的Packet 7。客户端收到响应数据返回了ack包并发起了关闭连接的请求。(fin包代表我要关闭)
2. 服务端也真够快,立马就回应ack包:“好,我收到你要关闭的请求了”。
3. 服务端认为可以关闭了,然后也向客户端发起了关闭请求。(fin包)
4. 客户端立马也回应ack包:“嗯,我们关闭吧”。
5. OK,游戏结束!


Json
xml
XML与HTML 的设计区别是: XML的核心是数据,其重点是 数据的内容。而 HTML 被设计用来 显示数据,其重点是数据的显示。
XML和HTML的语法区别:HTML的标记不是所有的都需要成对出现,XML则要求所有的标记必须成对出现;HTML标记不区分大小写,XML则 大小敏感,即区分大小写。
解析 XML 通常有两种方式,DOM 和 SAX:
           SAX解析XML,是基于事件通知的模式,一 边读取 XML 文档一边处理,不必等整个文档加载完之后才采取操作,当在读取解析过程中遇到需要处理的对象,会发出通知对其进行处理。
           DOM解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过遍历树结构可以检索任意XML节点,读取它的属性和值。而且通常情况下,可以 借助 XPath,直接查询XML 节点
    NSString *path=[[ NSBundle  mainBundlepathForResource: @"xml"  ofType: @"txt"];
   NSData  *data=[ NSData  dataWithContentsOfFile:path];
   NSXMLParser *xml=[[ NSXMLParser  allocinitWithData:data]; 
  xml. delegate= self;
 [xml  parse];
 


category
类别,category可以 在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修 。并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。
类别主要有 3 个作用
1. 给现有的类增加方法, 可以增加对象方法,也可以增加静态方法。
如果增加的方法是此类本来就有的方法,那么有可能覆盖原来的方法,也有可能不会覆盖。
2. 创建对私有方法的向前引用
3. 把同一类代码,分散到不同文件中实现,如NSIndexPath,有一部分方法就是在UITableView中写的。 

类别类扩展 的区别。
 
答案 category 和  extensions的不同在于 后者可以添加属性。另外后者添加的方法是必须要实现的。
extensions可以认为是一个私有的Category


CoreAnimation(系统的库)
    // 核心动画:CAAnimation
    //这个类是一个抽象类 ,不能直接创建对象
    // CAPropertyAnimation       是一个抽象的子类,它支持动画的 显示图层的关键路径中定制的属性。
    // CABasicAnimation           最基础的动画, 简单为图层提供属性修改
    // CAKeyframeAnimation       关键帧动画,可以指定动画每个阶段的值
    // CAAnimationGroup          动画组
    // CATransition                      提供了一个 图层变化的过渡效果
   //事务 CATransaction 管理线程安全的
   //隐式和显式

SDWebImage
原理。 它会把请求到的图片放到内存中显示出来,同时会把图片缓存到沙盒中。下次进入就算是断网也会从沙盒中读取出来。不过,这时候必须保证请求图片的URL存在,它是根据URL寻找图片的。
 
ShareSDK
ShareSDK用于向其他软件分享该软件。首先 到官网去申请注册,申请分享工具的Appkey。
 

ASIHTTPRequest
AFNetworking
ASI是基于: CFNetWork(底层通信库),效率稍高
AFNetWorking基于: NSURLConnectionNSOperation
ios7中2.0版本又可基于NSURLSession(与咱们熟悉的NSURLConnection是并列的)。
模块化:各种数据请求模块化,如jsno和xml,SDWebImage类单独分列开来。甚至plist文件也可直接获取。灵活性:很多地方用户可以自行扩展
1. 时间:AFN的第一个提交是2011年的1月1日,那个时候ASI早已是1.8+的版本了;而当AFN发布1.0版,2012年10月份的时候,ASI早早的已经停止更新了。

2. 用法 同样是发起一个最普通的异步请求,
AFN只需要调用一个 静态方法,但 代码可读性较差
ASI:虽然需要 调用多个实例方法才能完成一次请求,但是 示例看起来更清晰。

3. 高级功AFN 只封装了一些常用功能,满足基本需求,而直接忽略了很多扩展功能。例如:AFN默认 没有封装同步请求,如果开发者需要使用同步请求,则需要重写getPath:parameters:success:failure方法,对AFHTTPRequestOperation进行同步处理;而ASI则是直接通过调用一个startSynchronous方法。此外AFN针对JSON、XML、PList和Image四种数据结构封装了各自处理器,开发者可以把处理器注册到操作队列中,直接在回调方法中获得格式化以后的数据。
4. 性能对比:文件小于12K的测试中ASI的性能优势并没有非常明显,超过12K以后,ASI优势开始明显起来,每一次请求都要比AFN节约20% ~ 30%,近0.1秒。

MKNetworkKit:一个印度人写的,集合了两者的优点
 
Base64、Md5
Base64是可逆的,Md5 是不可逆的

Xcode,Instruments(检测iOS应用程序内存泄露的工具), Interface Builder(开发者可以使用Interface Builder来创建和修改应用程序的 图形用户界面。其数据以 XML的形式被储存在 .xib文件中。)
 


SBJSON                                             数据解析
EGOTableViewPullRefresh              下拉刷新
MBProgressHUD.SVProgressHUD  菊花
FMDB:sqlite                                   数据库
EGOImageView是一种实现网络图片的 异步加载缓存的第三方类库,具有相同功能的第三方类库还有SDWebImage。但是相比两个类库的安装和使用来说,EGOImageView更简单一些
XMPPFramework-master
     (XMPP协议是一个可用于即时通讯的协议(比如微信的语音聊天等等)。但是基于XMPP协议写一个即时通讯功能的App不是一件轻松的事情。这份类库就是专门为iOS和Mac所写的XMPP类库,提供了一系列的接口用于写基于XMPP的功能。这份类库是thread-safe的,基于GCD)
Bug查找 iOS可以 捕获 crash 日志,可以用系统提供的捕获异常日志的类相关的方法,把捕获的错误发回服务器,根据错误排查.
 







SBJSON  
无论是数组还是字典,都使用: objectWithString
它将支持ARC
// 请求完成调用的方法
- ( void)didFinishToDo:( ASIHTTPRequest *)request
{
     NSLog( @“—->%@",request. responseString );
    SBJSON *js = [[ SBJSON alloc] init];
    NSDictionary *dic = [js objectWithString:request. responseString error: nil];   
     // 装了所有的微博的信息
    NSArray * WBArr = [dic objectForKey: @"statuses"];
     for ( int i = 0 ; i < WBArr. count ; i++ )
   {
        WBModel *Awm = [[ WBModel alloc] init];  //一条微博的信息
         NSDictionary *dic = [WBArr objectAtIndex:i];
        NSString *headImageStr = [[dic objectForKey: @"user"] objectForKey: @"profile_image_url"];
        Awm. headImageURL = headImageStr;
        Awm. name = [dic objectForKey:[[dic objectForKey: @"user"] objectForKey: @"name"]];
        Awm. text = [dic objectForKey: @"text"];
        Awm. createTime = [dic objectForKey: @"created_at"];
        [ _wbModelArr addObject:Awm];
        [Awm release];
    }
    [ _tableView reloadData];  //刷新 tableview
}


- ( void)viewDidLoad
{
    [ super viewDidLoad];
     //创建地图
    //地图的类型
    //显示用户位置、信息
    map_view=[[ MKMapView alloc] initWithFrame: self. view. frame];
    map_view. delegate= self;
    map_view. mapType = MKMapTypeStandard;
     map_view. showsUserLocation = YES;
    [ self. view addSubview: map_view];
  
    //创建四个坐标点
    CLLocationCoordinate2D coord[ 4];
    coord[ 0] = CLLocationCoordinate2DMake( 41.000512, - 109.050116);
    coord[ 1] = CLLocationCoordinate2DMake( 41.002371, - 102.052066);
    coord[ 2] = CLLocationCoordinate2DMake( 36.993076, - 102.041981);
    coord[ 3] = CLLocationCoordinate2DMake( 36.99892, - 109.045267);
     //1.画一个多边形
    //2.画线
    //3.画圆
      MKPolygon *gon=[ MKPolygon polygonWithCoordinates:coord count: 4];
     MKPolyline *line=[ MKPolyline polylineWithCoordinates:coord count: 4];
     MKCircle *circle=[ MKCircle circleWithCenterCoordinate:coord[ 0] radius: 5000];
    [ map_view  addOverlay:gon];
    [ map_view  addOverlay:line];
    [ map_view addOverlay:circle];
}

//1.确定位置   按钮绑定:自定方法
-( void)mapBtn
{
     //1.2创建一个大头针(标记)
    MyAnn *ann=[[ MyAnn alloc] initWithTitle: @"大头针 " withSubtitle: @"具体地址 " withCoorinate: coord];
    [ map_view addAnnotation:ann];
     //map_view.centerCoordinate = map_view.userLocation.coordinate;
     //[map_view removeAnnotation:ann];
}

//3.注释表         代理方法   (pin: 大头针 ) MKPinAnnotationView *pin
- ( MKAnnotationView *)mapView:( MKMapView *)mapView viewForAnnotation:( id < MKAnnotation>)annotation
{
    static NSString  *identifier= @"AnnotationView";
    MKPinAnnotationView *pin = ( MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
   
    if (pin== nil) {
        pin= [[ MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
    }
     if ( map_view. userLocation==annotation) {
         return nil; //如果位置中 :有大头针 返回空
    }
     UIButton *Btn=[ UIButton buttonWithType: UIButtonTypeDetailDisclosure]; //按钮详情
    Btn. frame= CGRectMake( 0, 0, 80, 20);
    [Btn setTitle: @" 按钮 " forState: UIControlStateNormal];
     UIImageView *imageview=[[ UIImageView alloc] initWithFrame: CGRectMake( 0, 0, 32, 32)];
    imageview. image=[ UIImage imageNamed: @"head.png"];
     //3.1大头针的颜色
    //3.2能够显示弹出气泡
    //3.3右视图
    //3.4左视图
    pin. pinColor= MKPinAnnotationColorGreen;
    pin. canShowCallout= YES;
    pin. rightCalloutAccessoryView= Btn;
    pin. leftCalloutAccessoryView= imageview;
     return pin;
}

//4.轻轻点击 :气泡   代理方法
-( void)mapView:( MKMapView *)mapView annotationView:( MKAnnotationView *)view calloutAccessoryControlTapped:( UIControl *)control
{    //打开系统浏览器
    [[ UIApplication sharedApplication] openURL:[ NSURL URLWithString: @"http://www.baidu.com"]];
}

//4.渲染器         代理方法   (Renderer:渲染器 )
- ( MKOverlayRenderer *)mapView:( MKMapView *)mapView rendererForOverlay:( id < MKOverlay>)overlay
{
    //判断覆盖物类型
    if ([overlay isKindOfClass:[ MKPolygon class]]) {
         //创建多边形的渲染器    //设置多边形的填充色
         //边框,线的颜色 //线条的宽度
         MKPolygonRenderer *PR=[[ MKPolygonRenderer alloc] initWithPolygon:( MKPolygon *)overlay];
        PR. fillColor= [ UIColor cyanColor];
        PR. strokeColor= [ UIColor magentaColor];
        PR. lineWidth= 3;
        return PR;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值