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?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)