【问题标题】:ARC [rewriter] NSInvocation's setArgument is not safe to be used with an object with ownership other than __unsafe_unretainedARC [rewriter] NSInvocation 的 setArgument 不能安全地与所有权不是 __unsafe_unretained 的对象一起使用
【发布时间】:2012-09-21 12:24:45
【问题描述】:

我一直在将我的项目转换为 ARC,但我遇到了这个错误。

&object、&invocation 和 &callerToRetain 向我显示错误“[rewriter] NSInvocation 的 setArgument 不能安全地用于拥有除 __unsafe_unretained 之外的所有权的对象”

+ (void)performSelector:(SEL)selector onTarget:(id *)target withObject:(id)object amount:(void *)amount callerToRetain:(id)callerToRetain{if ([*target respondsToSelector:selector]) {
    NSMethodSignature *signature = nil;
    signature = [*target methodSignatureForSelector:selector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];

    [invocation setSelector:selector];

    int argumentNumber = 2;

    // If we got an object parameter, we pass a pointer to the object pointer
    if (object) {
        [invocation setArgument:&object atIndex:argumentNumber];
        argumentNumber++;
    }

    // For the amount we'll just pass the pointer directly so NSInvocation will call the method using the number itself rather than a pointer to it
    if (amount) {
        [invocation setArgument:amount atIndex:argumentNumber];
    }

    SEL callback = @selector(performInvocation:onTarget:releasingObject:);
    NSMethodSignature *cbSignature = [ASIHTTPRequest methodSignatureForSelector:callback];
    NSInvocation *cbInvocation = [NSInvocation invocationWithMethodSignature:cbSignature];
    [cbInvocation setSelector:callback];
    [cbInvocation setTarget:self];
    [cbInvocation setArgument:&invocation atIndex:2];
    [cbInvocation setArgument:&target atIndex:3];
    if (callerToRetain) {
        [cbInvocation setArgument:&callerToRetain atIndex:4];
    }

    CFRetain(invocation);

    // Used to pass in a request that we must retain until after the call
    // We're using CFRetain rather than [callerToRetain retain] so things to avoid earthquakes when using garbage collection
    if (callerToRetain) {
        CFRetain(callerToRetain);
    }
    [cbInvocation performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:[NSThread isMainThread]];
}}

请帮帮我。

【问题讨论】:

  • 你最后克服了吗?

标签: automatic-ref-counting nsinvocation


【解决方案1】:

默认情况下,NSInvocation 不会保留或复制给定参数以提高效率,因此作为参数传递的每个对象在调用调用时必须仍然存在。这意味着传递给 -setArgument:atIndex: 的指针被处理为 __unsafe_unretained。

如果你在 ARC 中使用 NSInvocation,最简单的方法是

  1. 在创建调用对象后调用[invocation retainArguments]。这意味着调用将保留给定的参数。
  2. 传递参数时,将它们转换为__unsafe_unretained
  3. 没有第 3 步。

【讨论】:

    猜你喜欢
    • 2012-01-30
    • 1970-01-01
    • 2012-03-09
    • 2023-03-03
    • 1970-01-01
    • 2015-05-01
    • 2012-01-25
    • 2012-02-28
    • 1970-01-01
    相关资源
    最近更新 更多