1、环境:编译器LLVM3.0以上,最好ios5,ios4.0有一些限制
2、最显著不同,不再使用 retain、release、autorelease,编译器会自动帮你插入,是编译器特性而不是运行时特性(weak指针系统是运行时特性),因此效率大于等于手动管理内存
3、原则:“只要还有一个变量指向对象,对象就会保持在内存中。”
4、关键词:
strong:能保住对象的生命
weak:不能保住对象,对象原所有者释放、weak自动变为nil,避免。“摇摆指针”和“zombies”
weak指针主要用于“父-子”关系,父亲拥有一个儿子的strong指针,因此是儿子的所有者;但为了阻止所有权回环,儿子需要使用weak指针指向父亲。典型例子是delegate模式,你的View Controller通过strong指针拥有一个UITableView,Table view的data source和delegate都是weak指针,指向你的View Controller。
5、ARC限制:首先ARC只能工作于Objective-C对象
strong指针会保持对象的生命,某些情况下你仍然需要手动设置这些指针为nil,何时你创建一个新对象时,都需要考虑谁拥有该对象,以及这个对象需要存活多久
6、有利于调试的编译参数:
Other Warning Flags 为 -Wall,这样编译器就会检查所有可能的警告,有助于我们避免潜在的问题。
Build Options下面的Run Static Analyzer选项也最好启用,这样每次Xcode编译项目时,都会运行静态代码分析工具来检查我们的代码。
7、不再需要property来管理私有变量了
IBOutlet 全部声名为weak
viewDidUnload()方法里面需要设置所有非outlet变量为nil,同样还有didReceiveMemoryWarning()方法。
@property总结:
• strong:等同于"retain",属性成为对象的拥有者
• weak:属性是weak pointer,当对象释放时会自动设置为nil,记住Outlet应该使用Weak
• unsafe_unretained:等同于之前的"assign",只有iOS 4才应该使用
• copy:和之前的copy一样,复制一个对象并创建strong关联
• assign:对象不能使用assign,但原始类型(BOOL、int、float)仍然可以使用
8、dealloc方法
另外启用ARC之后,dealloc方法在大部分时候都不再需要了
9、ARC仍然保留了AutoreleasePool,但是采用了新的Block语法,类似:
@autoreleasepool {
int retVal = UIApplicationMain(argc, argv, nil,
NSStringFromClass([AppDelegate class]));
return retVal;
}
10、Toll-Free Bridging
Core Foundation 的对象arc不负责管理,
例如:
CFStringRef s1 = (CFStringRef) [[NSString alloc] initWithFormat:@"Hello, %@!", name];
CFRelease(s1);
多数情况下,Objective-C对象和Core Foundation对象之间互相转换时,我们都应该使用__bridge。但是有时候我们确实需要给予ARC某个对象的所有权,或者解除ARC对某个对象的所有权。这种情况下我们就需要使用另外两种bridging casts:
• __bridge_transfer:给予ARC所有权 ( 与函数CFBridgingRelease() 效果一样,安全地将值传递给ARC )
• __bridge_retained:解除ARC所有权 (同样__bridge_retained也有一个辅助函数:CFBridgingRetain())
我们使用 __bridge_transfer 告诉ARC:"嘿!ARC,这个CFStringRef对象现在是一个NSString对象了,我希望你来销毁它,我这里就不调用CFRelease()来释放它了"。
总结:
• 使用CFBridgingRelease(),从Core Foundation传递所有权给Objective-C;
• 使用CFBridgingRetain(),从Objective-C传递所有权给Core Foundation;
• 使用__brideg,表示临时使用某种类型,不改变对象的所有权。
11、unsafe_unretained
编译器不会为其自动添加retain和release。unsafe_unretained只是为了兼容iOS 4,因为iOS 4没有weak pointer system。
12、
因此,如果你需要在ARC环境中使用Block,并且想避免捕获self,推荐采用如下代码模式:
__weak id weakSelf = self;
block = ^()
{
id strongSelf = weakSelf;
if (strongSelf != nil)
{
// do stuff with strongSelf
}
};
12、
在ARC中,所有指针变量默认都是nil
13、
#if __has_feature(objc_arc)
// do your ARC thing here
#endif
或者假如你还想支持老的GCC compiler:
#if defined(__has_feature) && __has_feature(objc_arc)
// do your ARC thing here
#endif