arc是一种编译时特性还是运行时特性
1个回答
展开全部
ARC本质 ARC编译器()特性运行特性更垃圾收器(GC) Automatic Reference Counting (ARC) is a compiler-level feature that simplifies the process of managing object lifetimes (memory management) in Cocoa applications. ARC相于MRC(Manual Reference Counting或称非ARC文我直使用MRC指代非ARC管理式)改进前技术本质没区别具体信息参考ARC编译器官文档 ARC启与关闭 同于XCode四创建工程选择关闭ARCXCode5创建工程默认启ARC没关闭ARC选项 需要特定文件启或关闭ARC工程选项选择Targets -> Compile Phases -> Compile Sources面找应文件添加flag: 打ARC:-fobjc-arc 关闭ARC:-fno-objc-arc 图: ARC修饰符 ARC主要提供四种修饰符别:__strong,__weak,__autoreleasing,__unsafe_unretained __strong 表示引用强引用应定义property"strong"所象没任何强引用指向才释放 注意:声明引用加修饰符引用默认强引用需要释放强引用指向象需要强引用置nil __weak 表示引用弱引用应定义property用"weak"弱引用影响象释放即要象没任何强引用指向即使依00弱引用象指向没用该象依释放象释放同指向弱引用自置nil技术叫zeroing weak pointer效防止效指针、野指针产__weak般用delegate关系防止循环引用或者用修饰指向由Interface Builder编辑与UI控件 __autoreleasing 表示autorelease pool自释放象引用MRC代autorelease用相同定义property能使用修饰符任何象property都应该autorelease型 见误解ARC没autorelease自释放看起像点余误解能源自于ARC自autorelease自混淆其实要看每iOS Appmain.m文件能知道autorelease仅存着并且变更fashion:需要再手工创建需要再显式调用[drain]释放内存池 两行代码意义相同 NSString *str = [[[NSString alloc] initWithFormat:@"hehe"] autorelease]; // MRC NSString *__autoreleasing str = [[NSString alloc] initWithFormat:@"hehe"]; // ARC 关于autoreleasepool做展详细信息参考官文档或者其文章 __autoreleasingARC主要用参数传递返值(out-parameters)引用传递参数(pass-by-reference)情况 __autoreleasing is used to denote arguments that are passed by reference (id *) and are autoreleased on return. 比用NSError使用: NSError *__autoreleasing error; if (![data writeToFile:filename options:NSDataWritingAtomic error:&error]) { NSLog(@"Error: %@", error); } (面writeToFileerror参数类型(NSError *__autoreleasing *)) 注意error定义strong型编译器帮隐式做事情保证终传入函数参数依__autoreleasing类型引用 NSError *error; NSError *__autoreleasing tempError = error; // 编译器添加 if (![data writeToFile:filename options:NSDataWritingAtomic error:&tempError]) { error = tempError; // 编译器添加 NSLog(@"Error: %@", error); } 所提高效率避免种情况我般定义error候其(实实==)声明__autoreleasing类型: NSError *__autoreleasing error; 加__autoreleasing相于MRC返值error做事情: *error = [[[NSError alloc] init] autorelease]; *error指向象创建放入autoreleasing pool等待使用结束自释放函数外error使用者并需要关*error指向象释放 另外点ARC所种指针指针 (NSError **)函数参数加修饰符编译器默认认定__autoreleasing类型 比面两段代码等同: - (NSString *)doSomething:(NSNumber **)value { // do something } - (NSString *)doSomething:(NSNumber * __autoreleasing *)value { // do something } 除非显式给value声明__strong否则value默认__autoreleasing 点某些类隐式使用自autorelease pool种候使用__autoreleasing类型要特别 比NSDictionary[enumerateKeysAndObjectsUsingBlock]: - (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error { [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){ // do stuff if (there is some error && error != nil) { *error = [NSError errorWithDomain:@"MyError" code:依 userInfo:nil]; }  }]; } 隐式创建autorelease pool面代码实际类似于: - (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error { [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){ @autoreleasepool // 隐式创建 { if (there is some error && error != nil) { *error = [NSError errorWithDomain:@"MyError" code:依 userInfo:nil]; }  } }]; // *error 已经dict做枚举遍历创建autorelease pool释放掉 :( } 能够使用*error我需要strong型临引用dict枚举Block用临引用保证引用指向象dict枚举Block释放确式: - (void)loopThroughDictionary:(NSDictionary *)dict error:(NSError **)error { __block NSError* tempError; // 加__block保证Block内修改 [dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { if (there is some error) { *tempError = [NSError errorWithDomain:@"MyError" code:依 userInfo:nil]; }  }] if (error != nil) { *error = tempError; } 
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询