- @interface NonARCObject : NSObject {
- NSString *name;
- }
- -(id)initWithName:(NSString *)name;
- @end
- @implementation NonARCObject
- -(id)initWithName:(NSString *)newName {
- self = [super init];
- if (self) {
- name = [newName retain];
- }
- return self;
- }
- -(void)dealloc {
- [name release];
- [Super dealloc];
- }
- @end
- @interface ARCObject : NSObject {
- NSString *name;
- }
- -(id)initWithName:(NSString *)name;
- @end
- @implementation ARCObject
- -(id)initWithName:(NSString *)newName {
- self = [super init];
- if (self) {
- name = newName;
- }
- return self;
- }
- @end
- 生成对象时,使用autorelease
- 对象代入时,先autorelease后再retain
- 对象在函数中返回时,使用return [[object retain] autorelease];
- 看到上面的例子,大家就知道了,以后写Objective-C的代码变得简单多了,因为我们不需要担心烦人的内存管理,担心内存泄露了
- 代码的总量变少了,看上去清爽了不少,也节省了劳动力
- 代码高速化,由于使用编译器管理引用计数,减少了低效代码的可能性
- 记住一堆新的ARC规则 — 关键字及特性等需要一定的学习周期
- 一些旧的代码,第三方代码使用的时候比较麻烦;修改代码需要工数,要么修改编译开关
- retain, release, autorelease, dealloc由编译器自动插入,不能在代码中调用
- dealloc虽然可以被重载,但是不能调用[super dealloc]
- 只要对象的持有者存在(对象被强参照),那么就可以使用该对象
- 对象失去了持有者后,即被破弃
(s1)
- __strong
- __weak
- NSString __weak *string = [[NSString alloc] initWithFormat:@"First Name: %@", [self firstName]];
- NSLog(@"string: %@", string); //此时 string为空
- __unsafe_unretained
- __autoreleasing
- - (void) generateErrorInVariable:(__autoreleasing NSError **)paramError {
- ....
- *paramError = [[NSError alloc] initWithDomain:@"MyApp" code:1 userInfo:errorDictionary];
- }
- ....
- {
- NSError *error = nil;
- [self generateErrorInVariable:&error];
- NSLog(@"Error = %@", error);
- }
- -(NSString *)stringTest
- {
- NSString *retStr = [NSString stringWithString:@"test"];
- return [[retStr retain] autorelease];
- }
- // 使用ARC
- -(NSString *)stringTest
- {
- __autoreleasing NSString *retStr = [NSString alloc] initWithString:@"test"];
- return retStr;
- }
- 代码中不能使用retain, release, retain, autorelease
- 不重载dealloc(如果是释放对象内存以外的处理,是可以重载该函数的,但是不能调用[super dealloc])
- 不能使用NSAllocateObject, NSDeallocateObject
- 不能在C结构体中使用对象指针
- id与void *间的如果cast时需要用特定的方法(__bridge关键字)
- 不能使用NSAutoReleasePool、而需要@autoreleasepool块
- 不能使用“new”开始的属性名称 (如果使用会有下面的编译错误”Property’s synthesized getter follows Cocoa naming convention for returning ‘owned’ objects”)
老版本的工程是可以转换成使用ARC的工程,转换规则包括:
1.去掉所有的retain,release,autorelease
2.把NSAutoRelease替换成@autoreleasepool{}块
3.把assign的属性变为weak
使用ARC的一些强制规定
1.不能直接调用dealloc方法,不能调用retain,release,autorelease,reraubCount方法,包括@selector(retain)的方式也不行
2.截图租户事故宣布dealloc方法来管理一些资源,但不能用来释放实例变量,也不能在dealloc方法里面去掉[super dealloc]方法,在ARC下父类的dealloc同样由编译器来自动完成
3.Core Foundation类型的对象任然可以用CFRetain,CFRelease这些方法
4.不能在使用NSAllocateObject和NSDeallocateObject对象
5.不能在c结构体中使用对象指针,如果有类似功能可以创建一个Objective-c类来管理这些对象
6.在id和void *之间没有简便的转换方法,同样在Objective-c和core Foundation类型之间的转换都需要使用编译器制定的转换函数
7.不能再使用NSAutoreleasePool对象,ARC提供了@autoreleasepool块来代替它,这样更加有效率
8.不能使用内存存储区(不能再使用NSZone)
9.不能以new为开头给一个属性命名
10.声明outlet时一般应当使用weak,除了对StoryBoard 这样nib中间的顶层对象要用strong
11.weak 相当于老版本的assign,strong相当于retain
对工程中的单个文件制定不使用ARC的方法:在targets的build phases选项下Compile Sources下选择要不使用arc编译的文件,双击它,输入
-fno-objc-arc
即可属性值 | 关键字 | 所有权 |
---|---|---|
strong | __strong | 有 |
weak | __weak | 无 |
unsafe_unretained | __unsafe_unretained | 无 |
copy | __strong | 有 |
assign | __unsafe_unretained | 无 |
retain | __strong | 有 |
- @property (nonatomic, readonly) NSString *name;
“ARC forbids synthesizing a property of an Objective-C object with unspecified ownership or storage attribute |
- @property (nonatomic, strong, readonly) NSString *name;