1. 什么是arc?(arc是为了解决什么问题诞生的?)
ARC: automatic reference counting,即自动引用计数,是苹果推出的一种内存管理机制。
ARC几个要点:
1、在对象被创建时 retain count +1,在对象被release时 retain count -1.当retain count 为0 时,销毁对象。
2、 程序中加入autoreleasepool的对象会由系统自动加上autorelease方法,如果该对象引用计数为0,则销毁。
那么ARC是为了解决什么问题诞生的呢?这个得追溯到MRC手动内存管理时代说起。 MRC下内存管理的缺点:
1.当我们要释放一个堆内存时,首先要确定指向这个堆空间的指针都被release了。(避免提前释放)
2.释放指针指向的堆空间,首先要确定哪些指针指向同一个堆,这些指针只能释放一次。(MRC下即谁创建,谁释
放,避免重复释放)
3.模块化操作时,对象可能被多个模块创建和使用,不能确定最后由谁去释放。
4.多线程操作时,不确定哪个线程最后使用完毕
2.请解释以下keywords的区别: assign vs weak, __block vs __weak
**assign vs weak**
assign于weak都是引用计数不变
assign的变量在释放后并不设置为nil,再去引用时会发生crash,weak变量释放后会设置为nil
assign用于基本数据类型(int,bool,float等),weak用于objct type
**Block __block __weak**
Block 是“带有自动变量值的匿名函数”,通常称为闭包
Block 中可以访问局部变量,但是不能修改
__block在arc和mrc模式下都可以使用,可以修饰对象,也可以修饰基本数据类型
__weak只能在arc模式下使用,只能修饰对象
__block 修饰的变量在Block中可以被修改
__weak 修饰的变量在Block中不能被修改
__block 修饰的变量引用计数+1
__weak 修饰的变量引用计数不变
__block 对象在arc模式下会导致循环引用,在mrc模式下会避免循环引用
__weak 只在arc模式下使用,会避免循环引用
**深入理解Block原理可参照这篇文章 http://blog.csdn.net/abc649395594/article/details/47086751**
3.__block在arc和非arc下含义一样吗?
在arc模式下,Block会被自动修改成__NSMallocBlock__,即强引用了一次,引用计数+1,mrc模式下则不会
在arc模式下,__block修饰的变量,引用计数+1,mrc下__block修饰的变量,引用计数不变
部持有的对象引用计数+1,需要调用release释放对象
4.使用atomic一定是线程安全的吗?
atomic修饰的属性不一定线程安全
atomic的操作是原子性的,但是并不意味着是线程安全的,它会增加正确的几率,能够避免一部分线程错误,但
仍然不是线程安全的。
atomic只是保证属性的读写是原子性的,但是仍然可能出现线程错误,如:当线程A进行写操作,这时其他线程的
读或者写操作会因为该操作而等待。当A线程的写操作结束后,B线程进行写操作,然后当A线程需要读操作时,却
获得了在B线程中的值,这就破坏了线程安全,如果有线程C在A线程读操作前release了该属性,那么还会导致程
序崩溃。所以仅仅使用atomic并不会使得线程安全,我们还要为线程添加lock来确保线程的安全。
5.描述一个你遇到过的retain cycle例子。
eg1:
@property (nonatomic,strong) HttpRequestHandler * handler;
@property (nonatomic,strong) NSData *data;
_handler = [httpRequestHandler sharedManager];
[ downloadData:^(id responseData){
_data = responseData;
}];
self 拥有_handler, _handler 拥有block, block拥有self(因为使用了self的_data属性,block会copy 一份self)
解决办法
__weak typedof(self)weakSelf = self
[ downloadData:^(id responseData){
weakSelf.data = responseData;
}];
eg2:
DoSomethingManager *manager = [[DoSomethingManager alloc] init];
manager.complete = ^{
//...complete actions
[manager otherAction];
manager.complete = nil;//如果不写这句,则造成retain cycle
};
eg3:
__block DoSomethingManager *manager = [[DoSomethingManager alloc] init];
manager.complete = ^{
//...complete actions
[manager otherAction];
manager = nil;//如果不写这句,则造成retain cycle
};
6.+(void)load; +(void)initialize;有什么用处?
7.为什么其他语言里叫函数调用, objective c里则是给对象发消息(或者谈下对runtime的理解)
http://www.csdn.net/article/2015-07-06/2825133-objective-c-runtime/1