iOS面试题汇总

1.简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?

OC中内存管理机制应该就是引用计数的增减吧,retainCount为0时释放该内存。 retain对应的是release,内存的释放用release。 alloc对应的是dealloc,内存的销毁用dealloc。

2.readwrite,readonly,assign,retain,copy,nonatomic,atomic,strong,weak属性的作用?
readwrite此标记说明属性会被当成读写的,这也是默认属性。 readonly此标记说明属性只可以读,也就是不能设置,可以获取。 assign不会使引用计数加1,也就是直接赋值。 retain会使引用计数加1。 copy建立一个索引计数为1的对象,在赋值时使用传入值的一份拷贝。 nonatomic:非原子性访问,多线程并发访问会提高性能。 atomic:原子性访问。 strong:打开ARC时才会使用,相当于retain。 weak:打开ARC时才会使用,相当于assign,可以把对应的指针变量置为nil。

3.线程是什么?进程是什么?二者有什么区别和联系?
线程,有时称为轻量级进程,是被系统独立调度和CPU的基本运行单位。 进程是操作系统中可以并行工作的基本单位。 一个应用程序里至少有一个进程,一个进程里至少有一个线程。

4.谈谈你对多线程开发的理解?iOS中有几种实现多线程的方法?GCD 与 NSOperation 的区别?
在一个进程中有多个线程,每个线程有自己单独的任务 优点效率快缺点不安全,耗费资源 第一种,使用@synchronized(self) 第二种,使用GCD 第三种,使用NSOperationQueue GCD 和 NSOperation 都是用于实现多线程: GCD 基于C语言的底层API,GCD主要与block结合使用,代码简洁高效。 NSOperation 属于Objective-C类,是基于GCD更高一层的封装。复杂任务一般用NSOperation实现。

5.线程同步和异步的区别?IOS中如何实现多线程的同步?
一个进程启动的多个不相干线程,它们相互之间关系为异步。 同步的话指的是多线程同时操作一个数据 这个时候需要对数据添加保护 这个保护就是线程的同步。 用GCD中的串行队列来解释多线程的同步,也就是队列中的任务为串行,它们各自对相邻的任务有依赖性,如果任务1不完成,那么任务2就不会开始,这就是同步

6.获取一台设备唯一标示的方法有哪些?
1.UDID 2.UUID 3.MAC ADDRESS 4.OPEN UDID 5.广告标识符 6.Vindor标示符 ios7之后用的时keychain(钥匙串)

7.Objective-C的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?
Objective-C的类不可以多重继承;可以实现多个接口(协议); Category是类别;一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。

8.设计模式是什么? 你知道哪些设计模式,并简要叙述?
设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型的事情。 1). MVC模式:Model View Control,把模型 视图 控制器 层进行解耦合编写。 2). MVVM模式:Model View ViewModel 把模型 视图 业务逻辑 层进行解耦和编写。 3). 单例模式:通过static关键词,声明全局变量。在整个进程运行期间只会被赋值一次。 4). 观察者模式:KVO是典型的通知模式,观察某个属性的状态,状态发生变化时通知观察者。 5). 委托模式:代理+协议的组合。实现1对1的反向传值操作。 6). 工厂模式:通过一个类方法,批量的根据已有模板生产对象。

9.MVC 和 MVVM 的区别?
1). MVVM是对胖模型进行的拆分,其本质是给控制器减负,将一些弱业务逻辑放到VM中去处理。 2). MVC是一切设计的基础,所有新的设计模式都是基于MVC进行的改进。

10.frame 和 bounds 有什么不同?
frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父view的坐标系统) bounds指的是:该view在本身坐标系统中的位置和大小。(参照点是本身坐标系统)

11.堆和栈的区别?
堆需要用户手动释放内存,而栈则是编译器自动释放内存

12.ios本地数据存储都有哪几种方式?iOS的沙盒目录结构是怎样的?
数据存储有四种方案:NSUserDefault、KeyChain、file、DB。 其中File有三种方式:plist、Archive(归档) DB包括:SQLite、FMDB、CoreData 沙盒结构: 1). Application:存放程序源文件,上架前经过数字签名,上架后不可修改。 2). Documents:常用目录,iCloud备份目录,存放数据。(这里不能存缓存文件,否则上架不被通过) 3). Library: Caches:存放体积大又不需要备份的数据。(常用的缓存路径) Preference:设置目录,iCloud会备份设置信息。 4). tmp:存放临时文件,不会被备份,而且这个文件下的数据有可能随时被清除的可能。

13.Objective-C 如何对内存管理的,说说你的看法和解决方法?
Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。 1). 自动内存计数ARC:由Xcode自动在App编译阶段,在代码中添加内存管理代码。 2). 手动内存计数MRC:遵循内存谁申请、谁释放;谁添加,谁释放的原则。 3). 内存释放池Release Pool:把需要释放的内存统一放在一个池子中,当池子被抽干后(drain),池子中所有的内存空间也被自动释放掉。内存池的释放操作分为自动和手动。自动释放受runloop机制影响。

14.浅拷贝和深拷贝的区别?
对一个实例进行深拷贝时当前类需要实现NSCopying协议。 浅拷贝:只复制指向对象的指针,而不复制引用对象本身。 深拷贝:复制引用对象本身。内存中存在了两份独立对象本身,当修改A时,A_copy不变。

15.什么情况使用 weak 关键字,相比 assign 有什么不同?
1.在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 来解决,比如: delegate 代理属性。 2.自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用 weak,自定义 IBOutlet 控件属性一般也使用 weak;当然,也可以使用strong。 IBOutlet连出来的视图属性为什么可以被设置成weak? 因为父控件的subViews数组已经对它有一个强引用。 不同点: assign 可以用非 OC 对象,而 weak 必须用于 OC 对象。 weak 表明该属性定义了一种“非拥有关系”。在属性所指的对象销毁时,属性值会自动清空(nil)。

16.怎么用 copy 关键字?
用途: 1. NSString、NSArray、NSDictionary 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary; 2. block 也经常使用 copy 关键字。 说明: block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.在 ARC 中写不写都行:对于 block 使用 copy 还是 strong 效果是一样的,但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。如果不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操作”,他们有可能会在调用之前自行拷贝属性值。这种操作多余而低效。

17.用@property声明的 NSString / NSArray / NSDictionary 经常使用 copy 关键字,为什么?如果改用strong关键字,可能造成什么问题?
用 @property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作(就是把可变的赋值给不可变的),为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。 1. 因为父类指针可以指向子类对象,使用 copy 的目的是为了让本对象的属性不受外界影响,使用 copy 无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本。 2. 如果我们使用是 strong ,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。 总结:使用copy的目的是,防止把可变类型的对象赋值给不可变类型的对象时,可变类型对象的值发送变化会无意间篡改不可变类型对象原来的值。

18.常见的 Objective-C 的数据类型有那些,和C的基本数据类型有什么区别?如:NSInteger和int
Objective-C的数据类型有NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值; NSInteger是基本数据类型,并不是NSNumber的子类,当然也不是NSObject的子类。 NSInteger是基本数据类型Int或者Long的别名(NSInteger的定义typedef long NSInteger),它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身是int还是long。

19.id 声明的对象有什么特性?
id 声明的对象具有运行时的特性,即可以指向任意类型的Objcetive-C的对象。

20.ViewController生命周期
按照执行顺序排列: 1. initWithCoder:通过nib文件初始化时触发。 2. awakeFromNib:nib文件被加载的时候,会发生一个awakeFromNib的消息到nib文件中的每个对象。 3. loadView:开始加载视图控制器自带的view。 4. viewDidLoad:视图控制器的view被加载完成。 5. viewWillAppear:视图控制器的view将要显示在window上。 6. updateViewConstraints:视图控制器的view开始更新AutoLayout约束。 7. viewWillLayoutSubviews:视图控制器的view将要更新内容视图的位置。 8. viewDidLayoutSubviews:视图控制器的view已经更新视图的位置。 9. viewDidAppear:视图控制器的view已经展示到window上。 10. viewWillDisappear:视图控制器的view将要从window上消失。 11. viewDidDisappear:视图控制器的view已经从window上消失。

21.描述应用程序的启动顺序
1. 程序入口main函数创建UIApplication实例和UIApplication代理实例。 2. 在UIApplication代理实例中重写启动方法,设置根ViewController。 3. 在第一ViewController中添加控件,实现应用程序界面。

22.Category(类别)、 Extension(扩展)和继承的区别
区别: 1. 分类有名字,类扩展没有分类名字,是一种特殊的分类。 2. 分类只能扩展方法(属性仅仅是声明,并没真正实现),类扩展可以扩展属性、成员变量和方法。 3. 继承可以增加,修改或者删除方法,并且可以增加属性。

23.我们说的OC是动态运行时语言是什么意思?
主要是将数据类型的确定由编译时,推迟到了运行时。简单来说, 运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。

24.为什么很多内置类如UITableViewControl的delegate属性都是assign/week而不是retain/strong?请举例说明。
避免循环引用 比如:对象A创建并引用到了对象B,对象B创建并引用到了对象C,对象C创建并引用到了对象B,这个时候B的引用计数是2,而C的引用计数是1,当A不用B的时候,就释放了B的所有权,这个时候C还引用对象B,所有B不会释放,引用计数为1;因为B也引用着对象C,B不释放,那么C就不会被释放,所有它们的引用计数都为1,并且永远不会被释放,所以形成了循环引用。

25.使用UITableView时候必须要实现的几种方法?
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

26.写一个便利构造器
MyView *view = [[MyView alloc]initWithName:name andAge:age]; return [view autorelease]; }

27.UIImage初始化一张图片有几种方法?简述各自的优缺点。
3种 imageNamed:系统会先检查系统缓存中是否有该名字的Image,如果有的话,则直接返回,如果没有,则先加载图像到缓存,然后再返回。 initWithContentsOfFile:系统不会检查系统缓存,而直接从文件系统中加载并返回。 imageWithCGImage:scale:orientation 当scale=1的时候图像为原始大小,orientation制定绘制图像的方向。

28.简述你对UIView,UIWindow和CALayer的理解
UIWindow是应用的窗口 UIView是创建窗口中的一个视图,可以响应交互事件 CALayer不可以响应事件

29.什么时候用Delegate(委托模式),什么时候用Notification(通知模式)?
1). 二者都用于传递消息,不同之处主要在于一个是一对一的,另一个是一对多的。 2). notification通过维护一个array,实现一对多消息的转发。 3). delegate需要两者之间必须建立联系,不然没法调用代理的方法;notification不需要两者之间有联系。

30.什么是 KVO 和 KVC?
1). KVC(Key-Value-Coding):键值编码 是一种通过字符串间接访问对象的方式(即给属性赋值) 举例说明: stu.name = @"张三" // 点语法给属性赋值 [stu setValue:@"张三" forKey:@"name"]; // 通过字符串使用KVC方式给属性赋值 stu1.nameLabel.text = @"张三"; [stu1 setValue:@"张三" forKey:@"nameLabel.text"]; // 跨层赋值 2). KVO(key-Value-Observing):键值观察机制 他提供了观察某一属性变化的方法,极大的简化了代码。 KVO只能被KVC触发,包括使用setValue:forKey:方法和点语法。 // 通过下方方法为属性添加KVO观察 -(void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context; // 当被观察的属性发送变化时,会自动触发下方方法 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{} KVC 和 KVO 的 keyPath 可以是属性、实例变量、成员变量。

31.KVC的底层实现?
当一个对象调用setValue方法时,方法内部会做以下操作: 1). 检查是否存在相应的key的set方法,如果存在,就调用set方法。 2). 如果set方法不存在,就会查找与key相同名称并且带下划线的成员变量,如果有,则直接给成员变量属性赋值。 3). 如果没有找到_key,就会查找相同名称的属性key,如果有就直接赋值。 4). 如果还没有找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey:方法。 这些方法的默认实现都是抛出异常,我们可以根据需要重写它们。

32.KVO的底层实现?
KVO基于runtime机制实现。

33.方法和选择器有何不同?
selector是一个方法的名字,方法是一个组合体,包含了名字和实现。

34.你是否接触过OC中的反射机制?简单聊一下概念和使用
1). class反射 通过类名的字符串形式实例化对象。 Class class = NSClassFromString(@"student"); Student *stu = [[class alloc] init]; 将类名变为字符串。 Class class =[Student class]; NSString *className = NSStringFromClass(class); 2). SEL的反射 通过方法的字符串形式实例化方法。 SEL selector = NSSelectorFromString(@"setName"); [stu performSelector:selector withObject:@"Mike"]; 将方法变成字符串。 NSStringFromSelector(@selector*(setName:));

35.调用方法有两种方式:
1). 直接通过方法名来调用。[person show]; 2). 间接的通过SEL数据来调用 SEL aaa = @selector(show); [person performSelector:aaa];

36.如何对iOS设备进行性能测试?
Profile-> Instruments ->Time Profiler

37.开发项目时你是怎么检查内存泄露?
1). 静态分析 analyze。 2). instruments工具里面有个leak可以动态分析。

38.什么是懒加载?
懒加载就是只在用到的时候才去初始化。也可以理解成延时加载。 我觉得最好也最简单的一个例子就是tableView中图片的加载显示了, 一个延时加载, 避免内存过高,一个异步加载,避免线程堵塞提高用户体验。

39.类变量的 @public,@protected,@private,@package 声明各有什么含义?
@public 任何地方都能访问; @protected 该类和子类中访问,是默认的; @private 只能在本类中访问; @package 本包内使用,跨包不可以。

40.如何访问并修改一个类的私有属性?
1). 一种是通过KVC获取。 2). 通过runtime访问并修改私有属性。

41.什么是block?
闭包(block):闭包就是获取其它函数局部变量的匿名函数。

42.block反向传值
在控制器间传值可以使用代理或者block,使用block相对来说简洁。 在前一个控制器的touchesBegan:方法内实现如下代码。 // OneViewController.m TwoViewController *twoVC = [[TwoViewController alloc] init]; twoVC.valueBlcok = ^(NSString *str) { NSLog(@"OneViewController拿到值:%@", str); }; [self presentViewController:twoVC animated:YES completion:nil]; // TwoViewController.h(在.h文件中声明一个block属性) @property (nonatomic ,strong) void(^valueBlcok)(NSString *str); // TwoViewController.m(在.m文件中实现方法) -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 传值:调用block if (_valueBlcok) { _valueBlcok(@"123456"); } }

43.block的注意点
1). 在block内部使用外部指针且会造成循环引用情况下,需要用__week修饰外部指针: __weak typeof(self) weakSelf = self; 2). 在block内部如果调用了延时函数还使用弱指针会取不到该指针,因为已经被销毁了,需要在block内部再将弱指针重新强引用一下。 __strong typeof(self) strongSelf = weakSelf; 3). 如果需要在block内部改变外部栈区变量的话,需要在用__block修饰外部变量。

44.什么是 RunLoop
从字面上讲就是运行循环,它内部就是do-while循环,在这个循环内部不断地处理各种任务。 一个线程对应一个RunLoop,基本作用就是保持程序的持续运行,处理app中的各种事件。通过runloop,有事运行,没事就休息,可以节省cpu资源,提高程序性能。 主线程的run loop默认是启动的。iOS的应用程序里面,程序启动后会有一个如下的main()函数 int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } }

45.什么是 Runtime? Runtime实现的机制是什么,怎么用,一般用于干嘛?
Runtime又叫运行时,是一套底层的C语言API,其为iOS内部的核心之一,我们平时编写的OC代码,底层都是基于它来实现的。 1). 使用时需要导入的头文件 2). Runtime 运行时机制,它是一套C语言库。 3). 实际上我们编写的所有OC代码,最终都是转成了runtime库的东西。 比如: 类转成了 Runtime 库里面的结构体等数据类型, 方法转成了 Runtime 库里面的C语言函数, 平时调方法都是转成了 objc_msgSend 函数(所以说OC有个消息发送机制) // OC是动态语言,每个方法在运行时会被动态转为消息发送,即:objc_msgSend(receiver, selector)。 // [stu show]; 在objc动态编译时,会被转意为:objc_msgSend(stu, @selector(show));

4). 因此,可以说 Runtime 是OC的底层实现,是OC的幕后执行者。
有了Runtime库,能做什么事情呢?
Runtime库里面包含了跟类、成员变量、方法相关的API。 比如: (1)获取类里面的所有成员变量。 (2)为类动态添加成员变量。 (3)动态改变类的方法实现。 (4)为类动态添加新的方法等。 因此,有了Runtime,想怎么改就怎么改。

46.分析json、xml的区别?json、xml解析方式的底层是如何处理的?
json数据小,易解析,不复杂xml数据较大,比较复杂 json中以key/value形式保存,大多数是字典数组模式 xml中则是<>

47.介绍一下XMPP?
XMPP是一种以XML为基础的开放式实时通信协议。 简单的说,XMPP就是一种协议,一种规定。就是说,在网络上传东西,XMM就是规定你上传大小的格式。

48.ViewController的didReceiveMemoryWarning是在什么时候被调用的?默认的操作是什么?
当应用程序的内存使用接近系统的最大内存使用时,应用会向系统发送内存警告,这时候系统会调用方法向所有的ViewController发送内存警告

49.面向对象的三大特征,并作简单的介绍。
封装、继承、多态 封装:将一个实例的所有属性封装到某个类中 继承:子类继承父类所有方法和属性 多态:父类指针指向子类对象

50.OC中创建线程的方法是什么?如果在主线程中执行代码,方法是什么?
// 创建线程的方法 - [NSThread detachNewThreadSelector:nil toTarget:nil withObject:nil] - [self performSelectorInBackground:nil withObject:nil]; - [[NSThread alloc] initWithTarget:nil selector:nil object:nil]; - dispatch_async(dispatch_get_global_queue(0, 0), ^{}); - [[NSOperationQueue new] addOperation:nil]; // 主线程中执行代码的方法 - [self performSelectorOnMainThread:nil withObject:nil waitUntilDone:YES]; - dispatch_async(dispatch_get_main_queue(), ^{}); - [[NSOperationQueue mainQueue] addOperation:nil];

51.tableView的重用机制?
UITableView 通过重用单元格来达到节省内存的目的: 通过为每个单元格指定一个重用标识符,即指定了单元格的种类,当屏幕上的单元格滑出屏幕时,系统会把这个单元格添加到重用队列中,等待被重用,当有新单元格从屏幕外滑入屏幕内时,从重用队列中找看有没有可以重用的单元格,如果有,就拿过来用,如果没有就创建一个来使用。

52.谈谈 UITableView 的优化
1). 正确的复用cell。 2). 设计统一规格的Cell 3). 提前计算并缓存好高度(布局),因为heightForRowAtIndexPath:是调用最频繁的方法; 4). 异步绘制,遇到复杂界面,遇到性能瓶颈时,可能就是突破口; 4). 滑动时按需加载,这个在大量图片展示,网络加载的时候很管用! 5). 减少子视图的层级关系 6). 尽量使所有的视图不透明化以及做切圆操作。 7). 不要动态的add 或者 remove 子控件。最好在初始化时就添加完,然后通过hidden来控制是否显示。 8). 使用调试工具分析问题。

53.如何实行cell的动态的行高
如果希望每条数据显示自身的行高,必须设置两个属性,1.预估行高,2.自定义行高。 设置预估行高 tableView.estimatedRowHeight = 200。 设置定义行高 tableView.estimatedRowHeight = UITableViewAutomaticDimension。 如果要让自定义行高有效,必须让容器视图有一个自下而上的约束。

54.如何重写类方法
1、在子类中实现一个同基类名字一样的静态方法 2、在调用的时候不要使用类名调用,而是使用[self class]的方式调用。原理,用类名调用是早绑定,在编译期绑定,用[self class]是晚绑定,在运行时决定调用哪个方法。

55.NSNotification和KVO的区别和用法是什么?什么时候应该使用通知,什么时候应该使用KVO,它们的实现上有什么区别吗?如果用protocol和delegate(或者delegate的Array)来实现类似的功能可能吗?如果可能,会有什么潜在的问题?如果不能,为什么?(虽然protocol和delegate这种东西面试已经面烂了…)
NSNotification是通知模式在iOS的实现,KVO的全称是键值观察 (Key-value observing),其是基于KVC(key-value coding)的,KVC是一 个通过属性名访问属性变量的机制。例如将Module层的变化,通知到多 个Controller对象时,可以使用NSNotification;如果是只需要观察某个 对象的某个属性,可以使用KVO。 对于委托模式,在设计模式中是对象适配器模式,其是delegate是指向 某个对象的,这是一对一的关系,而在通知模式中,往往是一对多的关 系。委托模式,从技术上可以现在改变delegate指向的对象,但不建议 这样做,会让人迷惑,如果一个delegate对象不断改变,指向不同的对 象。

56.你用过NSOperationQueue么?如果用过或者了解的话,你为什么要使用NSOperationQueue,实现了什么?请描述它和G.C.D的区别和类似的地方(提示:可以从两者的实现机制和适用范围来描述)。
使用NSOperationQueue用来管理子类化的NSOperation对象,控制 其线程并发数目。GCD和NSOperation都可以实现对线程的管理,区别 是 NSOperation和NSOperationQueue是多线程的面向对象抽象。项目中 使用NSOperation的优点是NSOperation是对线程的高度抽象,在项目中 使用它,会使项目的程序结构更好,子类化NSOperation的设计思路, 是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接 口简单,建议在复杂项目中使用。 项目中使用GCD的优点是GCD本身非常简单、易用,对于不复杂的多线 程操作,会节省代码量,而Block参数的使用,会是代码更为易读,建议 在简单项目中使用。

57.既然提到G.C.D,那么问一下在使用G.C.D以及block时要注意些什么?它们两是一回事儿么?block在ARC中和传统的MRC中的行为和用法有没有什么区别,需要注意些什么?
使用block是要注意,若将block做函数参数时,需要把它放到最 后,GCD是Grand Central Dispatch,是一个对线程开源类库,而Block 是闭包,是能够读取其他函数内部变量的函数。

58.对于Objective-C,你认为它最大的优点和最大的不足是什么?对于不足之处,现在有没有可用的方法绕过这些不足来实现需求。如果可以的话,你有没有考虑或者实践过重新实现OC的一些功能,如果有,具体会如何做?
最大的优点是它的运行时特性,不足是没有命名空间,对于命名冲 突,可以使用长命名法或特殊前缀解决,如果是引入的第三方库之间的 命名冲突,可以使用link命令及flag解决冲突。

59.OC和swift的区别
1)快速、现代、安全、互动,而且明显优于 Objective-C 语言; 2)可以使用现有的 Cocoa 和 Cocoa Touch 框架; 3)Swift 取消了 Objective-C 的指针/地址等不安全访问的使用; 4)提供了类似 Java 的名字空间(namespace)、泛型(generic)var、运算对象重载(operator overloading); 5)Swift 被简单的形容为 “没有 C 的 Objective-C”(Objective-C without the C); 6)为苹果开发工具带来了 Xcode Playgrounds 功能,该功能提供强大的互动效果,能让 Swift 源代码在撰写过程中实时显示出其运行结果; 7)基于 C 和 Objective-C,而却没有C的一些兼容约束; 8)采用了安全的编程模式; 9)界面基于 Cocoa 和 Cocoa Touch 框架; 10)舍弃 Objective C 早期应用 Smalltalk 的语法,保留了 Smalltalk 的动态特性,全面改为句点表示法; 11)类型严谨对比 Objective-C 的动态绑定。

【iOS面试题汇总】60.描述下SDWebImage里面给UIImageView加载图片的逻辑
SDWebImage 中为 UIImageView 提供了一个分类UIImageView+WebCache.h, 这个分类中有一个最常用的接口sd_setImageWithURL:placeholderImage:,会在真实图片出现前会先显示占位图片,当真实图片被加载出来后再替换占位图片。 加载图片的过程大致如下: 1.首先会在 SDWebImageCache 中寻找图片是否有对应的缓存, 它会以url 作为数据的索引先在内存中寻找是否有对应的缓存 2.如果缓存未找到就会利用通过MD5处理过的key来继续在磁盘中查询对应的数据, 如果找到了, 就会把磁盘中的数据加载到内存中,并将图片显示出来 3.如果在内存和磁盘缓存中都没有找到,就会向远程服务器发送请求,开始下载图片 4.下载后的图片会加入缓存中,并写入磁盘中 5.整个获取图片的过程都是在子线程中执行,获取到图片后回到主线程将图片显示出来 SDWebImage原理: 调用类别的方法: 1. 从内存(字典)中找图片(当这个图片在本次使用程序的过程中已经被加载过),找到直接使用。 2. 从沙盒中找(当这个图片在之前使用程序的过程中被加载过),找到使用,缓存到内存中。 3. 从网络上获取,使用,缓存到内存,缓存到沙盒。

    推荐阅读