iOS开发——ARC小记

iOS5 by Tutorials——ARC

1,ARC是编译时特性而不是运行时特性,弱指针系统除外。弱指针系统是iOS5以后才能支持的,如果想适配iOS4及之前,那么不能使用weak。
2,对象被销毁的几种情况:无指针指向、超出作用域(局部变量所在方法的结束或者该对象仅有一实例变量所指,而所在类被dealloc)
3,强类型指针可以保持对象存活。默认实例变量、参数和局部变量都是强类型。
4,__weak NSString *str = [[NSString alloc] initWithFormat:…]; NSLog(@”%@”, str);
上面代码输出(null)。因为weak指针不拥有对象,对象被赋值后立刻被释放。
如果是__weak NSString *str = [NSString stringWithFormat:@“”];就不会出现这种情况。原因:类方法创建的对象自动被autorelease,autorelease并不保证对象立刻被释放.alloc+init方法创建的对象会被retain.
5,网络请求成功时,HTTP状态码为200.
6,ARC是LLVM-3.0编译器的新特性。
7,转ARC:Edit\Refactor\Convert to Objective-C ARC。应该一次转完而尽量不要多次转。转换时,会要求勾选待转文件,未被选上的自动添加-fno-objc-arc设置。
8,通过Xcode Preference->General->Continue building after errors获取所有的error详细信息
9,当一个方法返回一个对象,并且改方法名不以alloc、init、copy、new、mutableCopy开头时,该对象会被autorelease
10,在除去dealloc方法之外的其他方法中,如果对Timer invalidate,一定要将该Timer赋值为nil。Timer自动对其Target持一个强引用。所以要通过要通过设置为nil消除保留环。另外,将Timer变量设置为__weak时,Timer被RunLoop所持有,而Timer又持有其Target,所以该Target在Timer invalidate之前是不会被释放的。
11,@class在非ARC下可以正常工作,即使没有#import,但是在ARC下需要#import。
12,ARC下,switch中的case内直接声明变量会报错switch case is in protected scope。声明变量的case需要用{}括起来。
13,ARC下,不允许在自定义的结构体中使用OC对象。
14,dealloc方法中依然可以使用实例变量。只有当该方法return时才会将对象释放。
15,viewDidUnLoad方法中应该将强引用置为nil,弱引用不需要。内存警告时会调用该方法。
16、OC对象转CF类型:__bridge标识符可以告诉编译器虽然OC对象被转成C“对象”了,但是依然要在合适的时间release。
CF类型转OC对象:__bridge_transfer标识符可以告诉编译器由编译器来管理C“对象”内存,也就是在合适的时间自动释放,我们就不需要再使用CFRelease了。此处如果使用__bridge会导致内存泄露,因为编译器不会调用CFRelease。这里也可以使用函数CFBridgingRelease,作用于__bridge_transfer一样。
使用CF类型时,凡是用到名字中还有Create、Copy、Retain的方法时都要向上述那样使用CFBridgingRelease()来让ARC管理内存。
OC对象转CF类型:如果打算手动调用CFReleaase来释放这个从OC对象转换而来的CF类型的内存,那么可以使用__bridge_retain标识符。此时如果使用__bridge,会引起crash,因为ARC也会释放一次该对象。与上面对应的,这里也有个方法CFBridgingRetain()。
如果希望在OC对象和CF类型之间进行转换,但不改变拥有关系,那么使用__bridge即可。
17,block创建时处于栈上,如果想让其处于堆上,需要调用copy方法或者使用Block_copy()函数。所以使用property声明一个block时,如果使用strong,那么很有可能app会因为block的释放而crash,应该使用copy使其保存到堆上。另外,如果是因为block之间赋值而导致crash,那么将值改成[block copy]即可,原理同上。
18,在block中使用实例变量依然会引起保留环,因为使用实例变量时底层是self->ivar,依然会持有self。
19,ARC之前,__block标识符修饰的变量不会被block所retain,但是ARC之后,该标识符只能起到在块内修改变量的作用了,应该使用__weak代替,然后在块内将其转换为strong。iOS4及之前版本时应该使用__block __unsafe_unretained
20,对nil发送消息、通过nil调用属性都是可以的,但是nil->ivar会使app crash。
21,示例:如果想延时处理一个block,并为之定义一个类。其构造方法如下:
SomeClass *var = [[SomeClass alloc] initWithDelay:5 block: ^(){
//do something without retain self
}];
如果该var是局部变量,那么这个block不会被执行,因为block并未持有任何对象。因此可以改成下面写法:
__block SomeClass *var = [[SomeClass alloc] initWithDelay:5 block:^() {
//do anything
var = nil;
}];
这样block重新截获self,直到block执行完之前,var对象都不会被释放。
22,使用NS_RETURNS_NOT_RETAINED或者NS_RETURNS_NOT_RETURNED
通知编译器无视方法名带来的retain或者autorelease问题。
23,只有当遇到性能问题,或者是自己编写返回out-parameter的方法(例如,NSError**)时才使用__autorelease标识符。out-parameter默认是__autorelease的。
24,当一组循环中需要创建大量对象时,为了防止内存不足,可以在循环内部添加@autorelease{},该标识符不会减慢app的运行速度。
25,CGPathCreate…方法创建的路径,需要进行手动release。例如,如果直接对SKShapeNode的path赋值为CGPathCreateWithRect(rect, NULL);则会引起一个内存泄露,因为没有对CGPathRef进行释放操作。

你可能感兴趣的:(ios,arc)