如何从int *转换为NSNumber *

时间:2018-08-08 16:39:35

标签: objective-c

我有以下代码。它可以编译,但是会崩溃。 我在做什么错了?

- (void)start: (int*)shouldPause
{        
    NSNumber * oShouldPause = (NSNumber *)shouldPause;
    [self performSelectorInBackground:@selector(runThread:) withObject: oShouldPause];
}

函数runThread是

- (void)runThread: (NSNumber*) shouldPause

通常,我想在线程外部和线程内部设置一些整数,以根据此整数更改行为。

感谢帮助!

2 个答案:

答案 0 :(得分:6)

NSNumber * oShouldPause = @(*shouldPause);

您所做的是一个常见错误。 NSNumber是对象,而int是原始类型。您将指向原始类型的指针转​​换为指向对象的指针。编译器允许它们都只是指针。此外,代码还希望有一个对象,试图发送一条消息并繁荣。出问题了。

很可能您不需要int*作为参数。仅int。因此,您需要按如下方式创建数字对象,而无需取消引用:

NSNumber * oShouldPause = @(shouldPause);

答案 1 :(得分:1)

正如安德烈·谢穆卡(Andrey Chemukha)所引用的,您不能将int *投射到NSNumber *

另一个可行的选择是,如果确实需要传递指针,则必须使用指针NSValue来传递指针和指针的内容(这是Andrey提供的代码)。例如,如果您有一个延迟的呼叫,但是您希望该呼叫具有最新的值,那么您可能需要它的一个示例。 注意,为简单起见,这里我忽略了同步方面。

在使用它时,您应该清理数据类型的使用并使用boolBOOL来保留您的标志。

- (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);
    }
}

注意,这里有提示!意味着,您需要保证指针的寿命,否则您将有一个悬空的指针。因此,这样做不是温柔的。

要明确,根据您的要求,我认为安德烈的答案是正确的选择。我只是将此添加为您的工具箱的另一个选项。

考虑到您的工作方式,您甚至不需要使用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的指针。通常,最好保持简单。