首页 > 系统 > iOS > 正文

iOS 面试题

2019-11-06 09:45:21
字体:
来源:转载
供稿:网友
● OC语言特点:继承、多态、封装1、是面向对象的设计语言2、仅支持单一父类继承,不支持多重继承跳出面向对象思想()多态      多态:不同对象以自己的方式响应相同的消息的能力叫做多态。 (自我理解:不同的类可以有相同的属性、方法)跳出面向对象思想()继承继承是罪恶,尽量不要继承。(避免:拔出萝卜带出泥)就我目前了解到的情况看,除了安居客的Pad App没有在框架级针对UIViewController有继承的设计以外,其它公司或多或少都针对UIViewController有继承,包括安居客iphone app(那时候我已经对此无能为力,可见View的架构在一开始就设计好有多么重要)。甚至有的还对UITableView有继承,这是一件多么令人发指,多么惨绝人寰,多么丧心病狂的事情啊。虽然不可避免的是有些情况我们不得不从苹果原生对象中继承,比如UITableViewCell。但我还是建议尽量不要通过继承的方案来给原生对象添加功能,前面提到的aspect方案和Category方案都可以使用。用Aspect+load来实现重载函数,用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 相当于 strong1、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增加1供newPt来管理0X1122这段内存;assign与retain:1、assign:简单赋值,不更改索引计数;2、assign的情况:NSString *newPt = [pt assing]; 此时newPt和pt完全相同地址都是0Xaaaa内容为0X1111即newPt只是pt的别名,对任何一个操作就等于对另一个操作,因此retainCount不需要增加;3、assign就是直接赋值;4、retain使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收;    5、retain的情况:NSString *newPt = [pt retain]; 此时newPt的地址不再为0Xaaaa,可能为0Xaabb但是内容依然为0X1111。因此newPt和pt都可以管理"abc"所在的内存,因此retainCount需要增加1 ;readonly:属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器。或者如果你使用@synthesize关键字,也是有读取器方法被解析  readwrite:说明属性会被当成读写的,这也是默认属性。设置器和读取器都需要在@implementation中实现。如果使用@synthesize关键字,读取器和设置器都会被解析;nonatomic:非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问;weak and strong property (强引用和弱引用的区别):1、 weak和strong属性只有在你打开ARC时才会被要求使用,这时你是不能使用retain release autorelease操作的,因为ARC会自动为你做好这些操作,但是你需要在对象属性上使用weak和strong,其中strong就相当于retain属性,而weak相当于assign。2、只有一种情况你需要使用weak(默认是strong),就是为了避免retain cycles(就是父类中含有子类{父类retain了子类},子类中又调用了父类{子类又retain了父类},这样都无法release)    3、声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。    ARC(Automatic Reference Counting):就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。该机能在iOS 5/ Mac OS X 10.7开始导入,利用Xcode4.2以后可以使用该特性。strong,weak,copy具体用法:1.具体一点:IBOutlet可以为weak,NSString为copy,Delegate一般为weak,其他的看情况。一般来说,类“内部”的属性设置为strong,类“外部”的属性设置为weak。说到底就是一个归属权的问题。小心出现循环引用导致内存无法释放。2.不用ARC的话就会看到很多retian。3.如果你写了@synthesize abc = _abc;的话,系统自动帮你声明了一个_abc的实例变量。  使用assign:对基础数据类型(NSInteger)和C数据类型(int, float, double, char,等)  使用copy:对NSString  使用retain:对其他NSObject和其子类 property简短的代码更易读:_property的写法比self.property更短,也更简单。我认为这样写出来的代码更方便阅读。执行速度更快,IPA体积更小我之前从来没想到过这两者之间的速度和应用体积会有很大差别。不过一个同行(来自国外著名的社交网络公司)告诉我,他们公司发现二者还是有不小的差距,如果你们的应用需要做一些深度优化,可以考虑一下把self.property换成_property。但我觉得,大部分应用都应该是不需要做这种深度优化的。循环引用问题微博上的@王_晓磊在评论中提到:直接用私有变量有个需要特别注意的地方,在 block 里直接写_property相当于self->_property,虽然没写 self,但是暗含了对 self 的retain,容易造成循环引用。要记得用 weakSelf/strongSelf 大法。浅复制和深复制的区别?shallow copy and deep copy答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身。  深层复制:复制引用对象本身。用网上一哥们通俗的话将就是:浅复制好比你和你的影子,你完蛋,你的影子也完蛋深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。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什么是平衡二叉树?           左右子树都是平衡二叉树且左右子树的深度差值的绝对值不大于1static 关键字的作用: (1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次, 因此其值在下次调用时仍维持上次的值; (2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问; (3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内; (4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝; (5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。  单例类: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 alloc] init];    });    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,当然也可以自定义NSOperation3.Grand Central Dispatch(简称GCD,iOS4才开始支持):提供了一些新特性、运行库来支持多核并行编程,它的关注点更高:如何在多个cpu上提升效率GCD1.用于解决多核并行运算的问题,可以平行操作更多的任务,会自动管理线程的生存周期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:nilwaitUntilDone:NO];    // GCD    dispatch_async(dispatch_get_main_queue(), ^{    });       // NSOperationQueue    [[NSOperationQueue mainQueue] addOperationWithBlock:^{    }];MVCMVC设计模式考虑三种对象:模型对象、视图对象和控制器对象。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 *)contextkeyPath就是要观察的属性值,options给你观察键值变化的选择,而context方便传输你需要的数据(注意这是一个void型)2 实现变化方法:-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object  change:(NSDictionary *)change context:(void *)contextchange里存储了一些变化的数据,比如变化前的数据,变化后的数据;如果注册时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?答:Delegate:针对   一对一  的关系,并且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,游戏结束!JsonxmlXML与HTML 的设计区别是:XML的核心是数据,其重点是数据的内容。而HTML 被设计用来显示数据,其重点是数据的显示。XML和HTML的语法区别:HTML的标记不是所有的都需要成对出现,XML则要求所有的标记必须成对出现;HTML标记不区分大小写,XML则 大小敏感,即区分大小写。解析 XML 通常有两种方式,DOM 和 SAX:           SAX解析XML,是基于事件通知的模式,一边读取XML文档一边处理,不必等整个文档加载完之后才采取操作,当在读取解析过程中遇到需要处理的对象,会发出通知对其进行处理。           DOM解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过遍历树结构可以检索任意XML节点,读取它的属性和值。而且通常情况下,可以借助XPath,直接查询XML节点。    NSString *path=[[NSBundle mainBundle] pathForResource:@"xml" ofType:@"txt"];  NSData  *data=[NSData dataWithContentsOfFile:path];  NSXMLParser *xml=[[NSXMLParser alloc] initWithData:data];   xml.delegate=self; [xml parse]; category类别,category可以 在不获悉,不改变原来代码的情况下往里面:添加新的方法,只能添加,不能删除修改。并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。类别主要有3个作用:1.给现有的类增加方法, 可以增加对象方法,也可以增加静态方法。如果增加的方法是此类本来就有的方法,那么有可能覆盖原来的方法,也有可能不会覆盖。2.创建对私有方法的向前引用。3.把同一类代码,分散到不同文件中实现,如NSIndexPath,有一部分方法就是在UITableView中写的。 类别、类扩展 的区别。
 答案category 和 extensions的不同在于后者可以添加属性。另外后者添加的方法是必须要实现的。
extensions可以认为是一个私有的CategoryCoreAnimation(系统的库)    //核心动画:CAAnimation    //这个类是一个抽象类 ,不能直接创建对象    //CAPropertyAnimation       是一个抽象的子类,它支持动画的显示图层的关键路径中定制的属性。    //CABasicAnimation           最基础的动画,简单为图层提供属性修改    //CAKeyframeAnimation     关键帧动画,可以指定动画每个阶段的值    //CAAnimationGroup          动画组    //CATransition                     提供了一个图层变化的过渡效果   //事务 CATransaction 管理线程安全的   //隐式和显式SDWebImage原理。它会把请求到的图片放到内存中显示出来,同时会把图片缓存到沙盒中。下次进入就算是断网也会从沙盒中读取出来。不过,这时候必须保证请求图片的URL存在,它是根据URL寻找图片的。 ShareSDKShareSDK用于向其他软件分享该软件。首先到官网去申请注册,申请分享工具的Appkey。 ASIHTTPRequestAFNetworkingASI是基于:CFNetWork(底层通信库),效率稍高AFNetWorking基于:NSURLConnection和NSOperationios7中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、md5Base64是可逆的,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 = [[SBJSONalloc]init];    NSDictionary *dic = [js objectWithString:request.responseStringerror:nil];       //装了所有的微博的信息    NSArray * WBArr = [dic objectForKey:@"statuses"];    for ( int i = 0 ; i < WBArr.count ; i++ )   {        WBModel *Awm = [[WBModelalloc]init]; //一条微博的信息        NSDictionary *dic = [WBArr objectAtIndex:i];        NSString *headImageStr = [[dicobjectForKey:@"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=[[MKMapViewalloc]initWithFrame:self.view.frame];    map_view.delegate=self;    map_view.mapType =MKMapTypeStandard;    map_view.showsUserLocation =YES;    [self.viewaddSubview: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=[MKPolygonpolygonWithCoordinates:coordcount:4];    MKPolyline *line=[MKPolylinepolylineWithCoordinates:coordcount:4];    MKCircle *circle=[MKCirclecircleWithCenterCoordinate:coord[0]radius:5000];    [map_view addOverlay:gon];    [map_view addOverlay:line];    [map_view addOverlay:circle];}//1.确定位置  按钮绑定:自定方法-(void)mapBtn{    //1.2创建一个大头针(标记)    MyAnn *ann=[[MyAnnalloc]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 *) [mapViewdequeueReusableAnnotationViewWithIdentifier:identifier];       if (pin==nil) {        pin= [[MKPinAnnotationView alloc] initWithAnnotation:annotationreuseIdentifier:identifier];    }    if (map_view.userLocation==annotation) {        return nil; //如果位置中:有大头针 返回空    }    UIButton *Btn=[UIButtonbuttonWithType:UIButtonTypeDetailDisclosure];//按钮详情    Btn.frame=CGRectMake(0,0,80,20);    [Btn setTitle:@" 按钮"forState:UIControlStateNormal];    UIImageView *imageview=[[UIImageViewalloc]initWithFrame:CGRectMake(0,0,32,32)];    imageview.image=[UIImageimageNamed:@"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:[NSURLURLWithString:@"http://www.baidu.com"]];}//4.渲染器        代理方法  (Renderer:渲染器)- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOverlay>)overlay{    //判断覆盖物类型    if ([overlay isKindOfClass:[MKPolygon class]]) {        //创建多边形的渲染器   //设置多边形的填充色        //边框,线的颜色//线条的宽度        MKPolygonRenderer *PR=[[MKPolygonRendereralloc]initWithPolygon:(MKPolygon *)overlay];        PR.fillColor= [UIColorcyanColor];        PR.strokeColor= [UIColormagentaColor];        PR.lineWidth= 3;        return PR;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表