1. 下面代码会出现什么问题(来源:Sunny)
@property (copy) NSMutableArray *mutableArray;
- 答案:
- 添加/删除/修改数组内元素时,程序会因为找不到对应的方法而崩溃
- 使用了
atomic
特质会影响性能(尽管没有名为atomic
的特质,但是如果某属性不具备nonatomic
特质,那它就是原子的atomic
)
- 解释:
- 因为copy就是复制一个不可变的NSArray对象
- 定义属性时,如果不明确指定
nonatomic
关键字,编译器在合成相关方法时会通过锁定机制确保其原子性,这会额外生成一些代码用于帮助编写多线程程序,由此会带来性能问题,通过声明nonatomic
特质可以节省这些虽然很小但是不必要的开销。
2. 下面代码输出什么(来源:Sunny)
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
});
NSLog(@"3");
}
- 答案:输出1之后程序死锁
-
解释:dispatch_sync文档中提到:
Calls to dispatch_sync() targeting the current queue will result in dead-lock. Use of dispatch_sync() is also subject to the same multi-party dead-lock problems that may result from the use of a mutex. Use of dispatch_async() is preferred.
sync到当前线程的block将会引起死锁,所以只会Log出1来后主线程就进入死锁状态,不会继续执行。
究其原因,还要看dispatch_sync做的事,它将一个block插入到queue中,这点和async没有区别,区别在于sync会等待到这个block执行完成后才回到调用点继续执行,而这个block的执行还依仗着viewDidLoad中dispatch_sync调用的结束,所以造成了循环等待,导致死锁。
3. 下面代码分别输出什么(来源:Sunny)
@implementation Son : Father
- (id)init {
self = [super init];
if (self) {
NSLog(@"%@", NSStringFromClass([self class]));
NSLog(@"%@", NSStringFromClass([super class]));
}
return self;
}
@end
- 答案:都输出”Son”
-
解释(来源:ChenYilong):这个题目主要是考察关于 Objective-C 中对 self 和 super 的理解。
我们都知道:self 是类的隐藏参数,指向当前调用方法的这个类的实例。那 super 呢?
很多人会想当然的认为“ super 和 self 类似,应该是指向父类的指针吧!”。这是很普遍的一个误区。其实 super 是一个 Magic Keyword, 它本质是一个编译器标示符,和 self 是指向的同一个消息接受者!他们两个的不同点在于:super 会告诉编译器,调用 class 这个方法时,要去父类的方法,而不是本类里的。
上面的例子不管调用[self class]还是[super class],接受消息的对象都是当前 Son *xxx 这个对象。
当使用 self 调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用 super 时,则从父类的方法列表中开始找。然后调用父类的这个方法。