objective-c – 为什么ARC迁移器说NSInvocation的-setArgument:不安全,除非参数是__unsafe_unretained?

objective-c – 为什么ARC迁移器说NSInvocation的-setArgument:不安全,除非参数是__unsafe_unretained?,第1张

概述我正在将一个代码块迁移到自动引用计数(ARC),并让ARC迁移器抛出错误 NSInvocation’s setArgument is not safe to be used with an object with ownership other than __unsafe_unretained 在代码上,我已经分配了一个对象使用类似的 NSDecimalNumber *testNumber1 = 我正在将一个代码块迁移到自动引用计数(ARC),并让ARC迁移器抛出错误

NSInvocation’s setArgument is not safe to be used with an object with
ownership other than __unsafe_unretained

在代码上,我已经分配了一个对象使用类似的

NSDecimalNumber *testNumber1 = [[NSDecimalNumber alloc] initWithString:@"1.0"];

然后将其设置为NSInvocation参数

[theInvocation setArgument:&testNumber1 atIndex:2];

为什么它阻止你这样做?使用__unsafe_unretained对象作为参数看起来也很糟糕。例如,以下代码导致ARC下的崩溃:

NSDecimalNumber *testNumber1 = [[NSDecimalNumber alloc] initWithString:@"1.0"];NSMutableArray *testArray = [[NSMutableArray alloc] init];__unsafe_unretained NSDecimalNumber *tempNumber = testNumber1;NSLog(@"Array count before invocation: %ld",[testArray count]);//    [testArray addobject:testNumber1];    SEL theSelector = @selector(addobject:);NSMethodSignature *sig = [testArray methodSignatureForSelector:theSelector];NSInvocation *theInvocation = [NSInvocation invocationWithMethodSignature:sig];[theInvocation setTarget:testArray];[theInvocation setSelector:theSelector];[theInvocation setArgument:&tempNumber atIndex:2];//        [theInvocation retainArguments];// Let's say we don't use this invocation until after the original pointer is gonetestNumber1 = nil;[theInvocation invoke];theInvocation = nil;NSLog(@"Array count after invocation: %ld",[testArray count]);testArray = nil;

因为临时的__unsafe_unretained tempNumber变量在原始指针设置为nil(模拟一种情况,其中在原始引用参数已经消失之后使用调用)的情况下不会保持在它上面,因为testNumber1被过度释放。如果-retainArguments行取消注释(使NSInvocation保持参数),此代码不会崩溃。

如果我直接使用testNumber1作为-setArgument:的参数,则会发生同样的崩溃,如果使用-retainArguments,它也是固定的。为什么,ARC迁移者说,使用强烈持有的指针作为NSInvocation的-setArgument:的参数是不安全的,除非你使用__unsafe_unretained的东西?

解决方法 这是一个完整的猜测,但是它可能是与参数传递的参考作为一个voID *?

在你提到的情况下,这似乎不是一个问题,但如果你打电话,例如。 getArgument:atIndex:那么编译器不会有任何方式知道返回的参数是否需要保留。

从NSInvocation.h:

- (voID)getArgument:(voID *)argumentLocation atIndex:(NSInteger)IDx;- (voID)setArgument:(voID *)argumentLocation atIndex:(NSInteger)IDx;

鉴于编译器不知道方法是否将通过引用返回(这两个方法声明具有相同的类型和属性),也许migrator(明智地)谨慎,并告诉您避免voID指针到强指针?

例如:

NSDecimalNumber* val;[anInvocation getArgument:&val atIndex:2];anInvocation = nil;NSLog(@"%@",val); // kaboom!__unsafe_unretained NSDecimalNumber* tempVal;[anInvocation getArgument:&tempVal atIndex:2];NSDecimalNumber* val = tempVal;anInvocation = nil;NSLog(@"%@",val); // fine
总结

以上是内存溢出为你收集整理的objective-c – 为什么ARC迁移器说NSInvocation的-setArgument:不安全,除非参数是__unsafe_unretained?全部内容,希望文章能够帮你解决objective-c – 为什么ARC迁移器说NSInvocation的-setArgument:不安全,除非参数是__unsafe_unretained?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1044404.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存