iOS 面试题总结(基础、内存管理、多线程等)

一、基础面试题

1. #import 跟 #include、@class有什么区别?#import<> 跟 #import""又什么区别?
  1. #import 和 #include 都能完整的包含某个文件的内容,#import 能防止同一个文件被包含多次
  2. @class 仅仅声明一个类名,并不会包含类的完整声明;@class还能解决循环包含的问题
  3. #import<> 用来包含系统自带的文件,#import" " 用来包含自定义的文件
2. 属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作用,在那种情况下用?
  1. readwrite:读写特性,同时生成getter 和 setter 方法的声明和实现
  2. .readonly:只读特性,只生成 getter 方法的声明和实现
  3. assign:set 方法的实现直接赋值,用于基本数据类型
  4. retain:set 方法的实现是 release 旧值, retain 新值,用于 OC 对象类型
  5. copy : set 方法的实现是 release 旧值,copy 新值 ,用于 NSString、block 等类型
  6. nonatomic:非原子性,set 方法的实现不加锁,不安全,性能高(atomic 性能低,atomic 通过锁定机制来确保其原子性,但只是读/写安全,不能绝对保证线程的安全,当多线程同时访问的时候,会造成线程不安全,可以是线程锁来保证线程的安全)
3. 写一个setter方法用于完成@property (nonatomic,retain)NSString *name,写一个setter方法用于完成@property(nonatomic,copy)NSString *name.
1>  @property (nonatomic, retain) NSString *name;
- (void)setName:(NSString *)name
{
  if (_name != name) {
    [_name release];
    _name = [name retain];
  }
}

2>  @property(nonatomic, copy) NSString *name;
- (void)setName:(NSString *)name
{
  if (_name != name) {
    [_name release];
    _name = [name copy];
  }
}
4. 对于语句NSString*obj = [[NSData alloc] init]; ,编译时和运行时obj分别是什么类型?
  1. 编译时是NSString类型
  2. 运行时是NSData类型
5. 常见的object-c的数据类型有那些, 和C的基本数据类型有什么区别?如:NSInteger和int
  1. OC常见的数据类型:NSString、NSArray、NSDictionary、NSData、NSNumber等
  2. OC对象需要手动管理内存,C的基本数据类型不需要管理内存
  3. NSInteger 是基本数据类型,并不是NSNumber 的子类,当然也不是NSObject的子类
  4. NSInteger 是基本数据类型 Int 或者 Long 的别名(NSInteger 的定义 typedef long NSInteger),它的区别在于NSInteger 会根据系统是 32 位还是64 位来决定其本身是 int 或者是 long。
6. id 声明的变量有什么特性?
  1. id 声明的变量指向任何 OC 对象
7. Objective-C如何对内存管理的,说说你的看法和解决方法?
  1. 每个对象都有一个引用计数器,每个新对象的计数器是1,当对象的引用计数为0时,就会被销毁
  2. 通过 retain 可以让引用计数器 +1 ,release 可以让引用计数器 -1
  3. 还可以通过 autorelease 管理内存
  4. 如果是 ARC,编译器会自动生成管理内存的代码
    注意:不管是 MRC 还是 ARC 都是在编译时完成的
8. 内存管理的几条原则时什么?按照默认法则.哪些方法生成的对象需要手动释放?在和property结合的时候怎样有效的避免内存泄露?
  1. 只要调用了 alloc、copy、new 方法产生的新对象,都必须在最后调用一次 release 或者是 autorelease
  2. 只要调用了 retain ,都必须在最后调用一次 release 或者 autorelease
  3. @property 如果用 copy 或者 retain ,就需要对不再使用的属性做一次 release 操作
9. 看下面的程序,三次NSLog会输出什么?为什么?
    NSMutableArray* ary = [[NSMutableArray array] retain];
    NSString *str = [NSString stringWithFormat:@"test"];
    [str retain];
    [ary addObject:str];
    NSLog(@"%ld", (unsigned long)[str retainCount]);
    [str retain];
    [str release];
    [str release];
    NSLog(@"%ld", (unsigned long)[str retainCount]);
    [ary removeAllObjects];
    NSLog(@"%ld", (unsigned long)[str retainCount]);

结果:-1-1-1-1代表没有引用计数或者引用计数非常大,因为str 是字符串,字符串在常量区,没有引用计数。引用计数为 -1,这可以理解为 NSString 实际上是一个字符串常量,是没有引用计数的(或者它的引用计数是一个很大的值(使用 %lu 可以打印查看)),对它做引用计数操作实际上没有任何影响
10. OC中创建线程的方法是什么?如果指定在主线程中执行代码?如何延时执行代码?
1> 创建线程的方法有:NSThread、CGD、NSOperation
2> 主线程中执行代码
 [self performSelectorOnMainThread: withObject: waitUntilDone:];
 [self performSelector: onThread:[NSThread mainThread] withObject: waitUntilDone:];
 dispatch_async(dispatch_get_main_queue(), ^{
});
3> 延时操作
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 
(int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){        
});
[self performSelector: withObject: afterDelay:];
[NSTimer scheduledTimerWithTimeInterval: target: selector: userInfo: repeats:];
11.浅拷贝与深拷贝的区别?
  1. 浅拷贝:对指针进行拷贝,不会产生新的对象
  2. 深拷贝:对指针和指针指向的内容进行拷贝,会生成新的对象
12.分类的作用是什么?实现类别和继承有什么区别?
  1. 分类可以在不修改原有类模型的基础上扩充方法
  2. 分类只能扩充方法,不能扩充成员变量;继承可以扩充方法和成员变量
  3. 继承会产生新的类
13. 分类和扩展的区别?
  1. 分类是有名称的,类扩展是没有名称的
  2. 分类只能扩充方法,不能扩充成员变量;类扩展可以扩充方法和成员变量
  3. 类扩展一般写在 .m 文件中,用来扩充私有的方法和成员变量
14.OC 中的协议和 Java 中的接口概念有什么不同?
  1. Java 的接口中声明的方法必须都实现
  2. OC 中 protocol 中声明的方法并一定要实现
15.什么是 KVC 和 KVO?
  1. KCV 是键值编码,可以通过一个字符串的 key(属性名)修改对象的属性的值
  2. KVO 是键值监听,可以监听一个对象属性值的改变
16.代理的作用是什么?
  1. 两个对象之间传递数据和消息
  2. 解耦,拆分业务逻辑
17.OC 中可修改和不可修改的类型?
  1. mutable 是可以变类型,比如 NSMutableArray ,可以动态添加元素
  2. immutable 是不可变类型,比如 NSArray, 固定的存储空间,不能添加元素
18.为什么说 OC 是动态运行时语言?
  1. 动态绑定:对象类型在运行时才能真正确定
  2. 多态性(不同对象以自己的方式去响应相同的消息的能力)
  3. 消息机制
19.通知和协议有什么不同之处?
  1. 通过 NSNotification 可以给多个对象传递数据和消息
  2. 通过 protocol 只能给一个对象传递数据和消息
20.什么是推送消息?
  1. 本地推送:程序内部弹出的通知到用户设备
  2. 远程推送:有推送服务器推送通知到用户设备
21.什么是多态?
  1. 多态:父类指针指向子类对象
22.怎么理解单例?
  1. 单例:保证程序运行过程中,永远只有一个对象实例
  2. 作用:全局共享一份资源、节省不必要的内存开销
23.怎么理解响应链?
  1. 事件响应链:包括点击事件、画画刷新事件等。
  2. UIResponder 有一个 nextResponder 属性,通过该属性可以组成一个响应者链,事件或消息在其路径上进行传递
  3. 如果 UIResponder 没有处理传给它的事件,会将未处理的消息转发给自己的 nextResponder
24.frame 和 bounds 有什么区别?
  1. frame:以父控件的左上角为坐标原点
  2. bounds:以控件本身的左上角为坐标原点
25.方法和选择器有什么不同?
  1. selector:是一个方法的名称,通过 selector 可以找到方法地址,进而调用这个方法
  2. method:是一个组合体,包含名字和实现
26.OC 的垃圾回收机制?
  1. OC 1.0没有垃圾回收
  2. OC 2.0有垃圾回收,但只能用在mac上
  3. iOS 中有 ARC机制,是编译器特性,垃圾回收是运行时特性
27.什么是NSOperation queue?
  1. 用来存放 NSOperation 对象的队列,可以用来异步执行一些操作
  2. 一般可以用在网络请求等耗时操作
28.什么是懒加载(延迟加载)?
  1. 延迟加载:比如控制器的 view ,在第一次用到 view 时才会调用 loadView方法进行创建
29.是否在一个控制器中嵌入两个 tableView 控制器?
  1. 技术角度上,一个控制器添加两个list 是没有问题的
30.一个 tableView 是否可以关联两个不同的数据源?
  1. 从对象属性上分析,tableView只有一个dataSource属性。当然,真要使用2个不同的数据源,还是有其他办法解决的
31.什么时候用 NSMutableArray?什么时候用NSArray?
  1. 当数组元素需要动态添加或者删除时用可变数组
  2. 当数组元素固定不变是用不可变数组
32.在应用中可以创建多少autorelease对象,是否有限制?
  1. 没有限制
33.如果我们不创建内存池,是否有内存池提供给我们?
  1. 系统会默认会不定时地创建和销毁自动释放池
34.什么时候需要在程序中创建内存池?
  1. 用户自己创建的数据线程,则需要创建该线程的内存池
35.什么时候内存计数会增加?
  1. 当做一次 retain 或者是 copy 操作的时候,内存引用计数都会增加1
36.类NSObject的那些方法经常被使用?
  1. NSObject是Objetive-C的基类,其由NSObject类及一系列协议构成。
  2. NSObject 常见的类方法有:alloc、class、 description 对象方法init、dealloc、– performSelector:withObject:afterDelay:等经常被使用
37.什么是简便构造方法?
  1. 简便的构造方法一般由 Cocoa Touch 框架提供,如 NSNumber 的 + numberWithBool: + numberWithChar: + numberWithDouble: + numberWithFloat: + numberWithInt:
  2. Foundation 下部分类均有简便构造方法,我们可以通过简便构造方法获取系统给我们创建好的对象,并且不需要手动释放。
38.如何使用Xcode设计通用应用?
  1. 使用MVC模式设计应用,其中Model层完成脱离界面,即在Model层,其是可运行在任何设备上,在controller层,根据iPhone与iPad(独有UISplitViewController)的不同特点选择不同的viewController对象。在View层,可根据现实要求,来设计,其中以xib文件设计时,其设置其为universal。
39.在Objetive-C什么时原子关键字?
  1. atomic:原子性,会对 setter 方法的实现进行加锁
40.UIView的动画效果有那些?
有很多,如  
UIViewAnimationOptionCurveEaseInOut  
UIViewAnimationOptionCurveEaseIn     
UIViewAnimationOptionCurveEaseOut   
UIViewAnimationOptionTransitionFlipFromLeft
UIViewAnimationOptionTransitionFlipFromRight
UIViewAnimationOptionTransitionCurlUp
UIViewAnimationOptionTransitionCurlDown 
41.在iPhone应用中如何保存数据?
  1. 属性列表
  2. NSUserDefault
  3. 键值归档(NSKeyedArchiver、NSCoding)
  4. SQLite 数据库
  5. Core Data
42.什么是NSManagedObject模型?
  1. NSManagedObject 是 NSObject 的子类 ,也是 Core Data 的重要组成部分,它是一个通用的类,实现了Core Data 模型层所需的基本功能,用户可通过子类化 NSManagedObject,建立自己的数据模型。
43.什么是谓词?
谓词是通过NSPredicate,是通过给定的逻辑条件作为约束条件,完成对数据的筛选。

 predicate = [NSPredicate predicateWithFormat:@"customerID == %d",n];

 a = [customers filteredArrayUsingPredicate:predicate];
44.OC 有多继承吗?没有的话用什么代替?
  1. OC 是单继承,没有多继承
  2. 可以用分类或者是协议来代替多继承
45.OC 有私有方法吗?私有变量呢?
  1. OC 没有类似 @private 的修饰词来修饰方法,只要写在 .h 文件中,就是公共方法
  2. 如果不在 .h 文件中声明,只在 .m 文件中实现,或在 .m 文件的 Class Extension 里面声明,那么基本上和私有方法差不多,可以使用类扩展 来增加私有方法和私有变量
  3. 使用 @private 修饰的全局变量是私有变量
46.关键字 const 什么含义?
const int a;
int const a;
const int *a;
int const *a;
int * const a;
int const * const a;

1.前面两个的作用是一样的:a 是一个常整形数
2.第三、四个意味着 a 是一个指向常整型数的指针(整型数是不可修改的,但是指针可以)
3.第五个意思:a 是一个指向整型数的常指针(指针指向的整型数是可以修改的,但是指针是不可修改的)
4.最后一个意思:a 是一个指向常整型数的常指针(指针指向的整型数是不可修改的,同时指针也是不可修改的)

47.static 的作用?
  1. static 修饰的函数是一个内部函数,只能在本文件中调用,其他文件不能调用
  2. static 修饰的全局变量是一个内部变量,只能在本文件中使用,其他文件不能使用
  3. static 修饰的局部变量只会初始化一次,并且在程序退出时才会回收内存
48.线程和进程的区别?
  1. 一个应用程序对应一个进程,一个进程帮助程序占据一块存储空间。也有多个进程应用(如浏览器)
  2. 要想在进程中执行任务,进必须开启线程,一个线程代表一个任务
  3. 一个进程中允许开启多条线程,也就是可以同时执行多个任务
49.堆和栈的区别?
  1. 堆空间的内存是动态分配的,一般存放对象,并且需要手动释放内存
  2. 栈空间的内存由系统自动分配,一般存放局部变量等,不需要手动管理内存
50.为什么很多内置的类,如TableView 的delegate 的属性是 assign 而不是 retain?
  1. tableView 的代理一般都是它所属的控制器,控制器会对它内部的 view 做一次 retain 操作
  2. 假设 tableView 也对代理做一次 retain 操作,那么久会出现循环 retain 问题
51.定义属性,什么时候用 copy、assign、retain?
  1. copy:NSString、Block 等类型
  2. assign:非 OC 对象类型,基本数据类型(两个对象相互引用的时候,一端用 retain 一端用 assign)
  3. retain:OC对象类型
52.对象是什么时候被释放的?
  1. 每个对象都有一个引用计数器,每个新对象的引用计数器都是1,当对象引用计数器为0时,就会被销毁
53.tableView的重用机制?
  1. 这里只是简述:将离开屏幕的cell放到缓存池,重新拿来显示到屏幕的其他位置(其他自己详细描述)
54.ViewController 的loadView、viewDidLoad、viewDidUnload分别是什么时候调用的,在自定义ViewCointroller时在这几个函数中应该做什么工作?
  1. loadView:但第一次使用控制器的view时,会调用 loadView 方法创建 view。 一般在这里自定义 view
  2. viewDidLoad:当控制器的 view 创建完毕是回调用,也就是在 loadView 后调用。一般在这里添加子控件、初始化数据
  3. viewDidUnload:当控制器的 view 因为内存警告被销毁是调用。一般在这里回收跟界面相关的资源(界面都会销毁了,跟界面相关的资源肯定不要了)
55.ViewController的didReceiveMemoryWarning是在什么时候调用的?默认的操作是什么?
  1. 当程序接收到系统内存警告时,就有可能调用控制器的 didReceiveMemoryWarning 方法
  2. 它的默认做法是:当控制器的 view 不在窗口上显示时, 就会直接销毁,并且调用 viewDidUnload 方法
56.怎么理解 MVC ,在Cocoa 中MVC 是怎么实现的?
  1. M:model,模型 ,封装数据
  2. V:view,视图界面,负责展示数据
  3. C:Controller,控制器,负责提供数据给界面
57.self. 跟 self -> 有什么区别?
  1. self. 是调用 get 方法或者是 set 方法
  2. self 是当前本身,是一个指向当前对象的指针
  3. self -> 是直接访问成员变量
58.id、nil 代表什么?
  1. id 类型的指针可以指向任何 OC 对象
  2. nil 代表空值(空指针的值)
59.如何对 iOS 设备进行性能测试?
  1. Timer Profile

二、iOS-内存管理

1. 什么情况使用 weak 关键字,相比 assign 有什么不同?
  • 什么时候使用 weak 关键字?
    1. 在 ARC 中,在有可能出现循环引用的时候,往往要通过让其中一端使用 weak 关键字来解决,如:delegate 代理属性
    2. 自身已经对它进行过一起强引用,没有必要再强引用一次,此时也会使用 weak 关键字,自定义 IBOutlet 控件属性一般也使用 weak ;当然也可以使用 strong 。
  • 不同点:
  1. weak 此特性表明该属性定义一种 “非拥有关系”。为这种属性设置新值时,设置的方法既不保留新值,也不释放旧值。此特质同 assign 类似,然而在属性所指的对象遭到摧毁时,属性值也会清空,而 assign 的设置方法只会针对纯量类型(CGFloat、NSInteger)的简单赋值操作。
  2. assign 可以用 非 OC对象,为 weak 必须用于 OC 对象
2.如何让自己的类用 copy 修饰符?如何重写带 copy 关键字的 setter?
  1. 若想让自己自定义的对象具有copy功能,则需要实现 NSCopying 协议。如果自定的对象分为可变版本和不可变版本,则需要同时实现 NSCopying 和 NSMutableCopying 协议。
具体步骤:
声明该类遵从 NSCopying 协议,实现 NSCopying 协议。该协议只有一个方法:

- (id)copyWithZone:(NSZone *)zone;
注意:一提到让自己的类用 copy 修饰符,我们总是想覆写copy方法,其实真正需要实现的却是 “copyWithZone” 方法。

- 重写带 copy 关键字的 setter 例如:

- (void)setName:(NSString *)name {
   //[_name release];
   _name = [name copy];
}
3.深拷贝与浅拷贝
  1. 浅拷贝只是针对指针的拷贝,拷贝后两个指针指向同一个内存空间。
  2. 深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。
  3. 但对象中存在指针成员时,除了在复制对象时需要考虑自定义拷贝构造函数,还应该考虑以下两种情况:1.当函数的参数为对象时,实参传递给形参的实际上是实参的一个拷贝对象,系统自动通过拷贝构造函数实现;2.当函数的返回值为一个对象时,该对象实际上是函数内对象的一个拷贝,用于返回函数调用处。copy 方法:如果是非可扩展类对象,则是浅拷贝。如果是可扩展类对象,则是深拷贝。mutableCopy 方法:无论是可扩展对象还是不可扩展对象,都是深拷贝。
持续更新。。。。 欢迎指导
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值