如何将int*转换为NSNumber*

3
我有以下代码。它编译通过,但会崩溃。 我做错了什么?
- (void)start: (int*)shouldPause
{        
    NSNumber * oShouldPause = (NSNumber *)shouldPause;
    [self performSelectorInBackground:@selector(runThread:) withObject: oShouldPause];
}

并且函数runThread是

- (void)runThread: (NSNumber*) shouldPause

通常,我想设置一些整数,这些整数在线程外部和线程内部改变行为取决于该整数。

感谢您的帮助!


1
shouldPause 应该是一个标量 int 还是一个指针? - vadian
2个回答

8
NSNumber * oShouldPause = @(*shouldPause);

你所犯的错误很常见。 NSNumber 是一个对象,而 int 是一种原始类型。你将指向原始类型的指针转换为指向对象的指针。编译器允许这样做,因为它们都只是指针。进一步地,代码期望一个对象,试图发送消息,结果出现问题。
最有可能的是,你不需要 int * 作为参数,只需要 int 。 因此,你需要按照以下方式创建数字对象,而不需解引用:
NSNumber * oShouldPause = @(shouldPause);

你的第一次编辑篡改了我正在输入的答案,因此获得了我的投票;原始类型和对象类型之间存在巨大的区别,并且使用标记指针,NSNumber甚至不一定存在于内存中。对象具有反射性和层次结构,而原始类型则没有。在机器级别上,intNSNumber看起来完全不同,这就是指针转换有意义的原因。 - Tommy

2
正如Andrey Chemukha所引用的那样,你不能将int*强制转换为NSNumber*。
如果你确实需要传递指针而不是指针内容(这就是Andrey提供代码的目的),另一个可行的选择是使用NSValue。你可能需要这样做的一个例子是,如果你有一个延迟调用,但你希望该调用具有最新的值。请注意,这里为简单起见忽略了同步方面的问题。
当你在处理数据类型时,你应该清理一下,并使用bool或BOOL来保存你的标志。
- (void)start:(BOOL *)shouldPause {
    NSValue *oShouldPause = [NSValue valueWithPointer:shouldPause];
    [self performSelectorInBackground:@selector(runThread:) withObject:oShouldPause];
}

- (void)runThread:(NSValue *)value {
    BOOL *shouldPause = (BOOL *) [value pointerValue];
    if (shouldPause) {
        // Pause-a-licous
        NSLog(@"shouldPause is %d", *shouldPause);
    }
}

注意:以下方法有局限性!! 这意味着您需要保证指针的生命周期,否则您将拥有一个悬挂指针。因此,这种做法不适合胆小者。

为了明确起见,根据您的要求,我认为Andrey的答案是正确的。我只是将其添加为您工具箱中的另一个选项。

另外,考虑到您的操作方式,您甚至不需要使用performSelector:withObject:

- (void)startAlternate:(BOOL *)shouldPause {
    [self runThreadAlternate:shouldPause ? *shouldPause : NO];
}

- (void)runThreadAlternate:(BOOL)shouldPause {
    // Pause-o-matic
    NSLog(@"shouldPause is %d", shouldPause);
}

我可能会进一步改变参数为 startAlternate: 为一个 BOOL 而不是 BOOL 指针。通常情况下,保持简单最好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接