Nic*_*son 18 objective-c clang automatic-ref-counting
使用ARC进行编译时,方法参数通常似乎保留在方法的开头并在结束时释放.这个保留/释放对似乎是多余的,并且与ARC"产生你本来会编写的代码"的想法相矛盾.在那些黑暗的,ARC之前的日子里没有人对所有方法论证进行额外的保留/释放只是为了安全起见,是吗?
考虑:
@interface Test : NSObject
@end
@implementation Test
- (void)testARC:(NSString *)s
{
[s length]; // no extra retain/release here.
}
- (void)testARC2:(NSString *)s
{
// ARC inserts [s retain]
[s length];
[s length];
// ARC inserts [s release]
}
- (void)testARC3:(__unsafe_unretained NSString *)s
{
// no retain -- we used __unsafe_unretained
[s length];
[s length];
// no release -- we used __unsafe_unretained
}
@end
Run Code Online (Sandbox Code Playgroud)
当在Xcode 4.3.2在释放模式编译的组件(例如,我很能理解它)包含到电话objc_retain和objc_release在第二个方法的开始和结束.这是怎么回事?
这不是一个大问题,但是当使用Instruments分析对性能敏感的代码时,会出现这种额外的保留/释放流量.看起来你可以装饰方法参数__unsafe_unretained以避免这种额外的保留/释放,就像我在第三个例子中所做的那样,但这样做感觉非常恶心.
zou*_*oul 18
请参阅Objc语言邮件列表中的回复:
当编译器对某个函数或方法的内存管理行为一无所知时(这种情况会发生很多),编译器必须假定:
1)函数或方法可能完全重新排列或替换应用程序的整个对象图(它可能不会,但它可以).2)调用者可能是手动引用计数代码,因此传入参数的生命周期实际上是不可知的.
鉴于#1和#2; 并考虑到ARC 必须决不允许一个对象被过早地释放,那么这两个假设压力,以保持在对象往往不是通过编译器.
我认为主要的问题是你的方法的主体可能导致争论被释放,因此ARC必须采取防御措施并保留它们:
- (void) processItems
{
[self setItems:[NSArray arrayWithObject:[NSNumber numberWithInt:0]]];
[self doSomethingSillyWith:[items lastObject]];
}
- (void) doSomethingSillyWith: (id) foo
{
[self setItems:nil];
NSLog(@"%@", foo); // if ARC did not retain foo, you could be in trouble
}
Run Code Online (Sandbox Code Playgroud)
这可能也是您在方法中只有一次调用时看不到额外保留的原因.
| 归档时间: |
|
| 查看次数: |
3867 次 |
| 最近记录: |