NSOperationQueue 方法参数变空

NSOperationQueue methods parameter are becoming empty

我在使用 NSOperationQueue 时遇到问题,如果我将相同的操作添加 200 次,方法的行为与预期一致。 但是,如果我将 for 循环增加到 500 次,当队列开始执行任务时,参数将变为空。下面是代码片段。

- (void)someMethod:(char *)param1 {
    NSBlockOperation *theOp = [NSBlockOperation blockOperationWithBlock: ^{
        // use this paramter and do something
    }];
    [[MyQueueService sharedMyQueueService] operationQueue] addOperation:theOp];
}

这就是我调用上述方法的方式

for (int index = 1; index < 500; index++) {
    MyClass *classInstance = [[MyClass alloc] init];
    NSString *parm1 = [NSString stringWithFormat:@"%d", index];
    [classInstance someMethod:(char *)[string cStringUsingEncoding:NSUTF8StringEncoding]];
}

此处变空即“”,如果我运行相同的方法500次,因此我无法执行其他操作。请帮我解决这个问题。

问题不在于 NSOperationQueue。问题是 char * 的使用。作为 documentation for cStringUsingEncoding says:

The returned C string is guaranteed to be valid only until either the receiver is freed, or until the current memory is emptied, whichever occurs first. You should copy the C string or use getCString:maxLength:encoding: if it needs to store the C string beyond this time.

最重要的是,像 char * 这样的简单 C 指针不参与(自动)引用计数。您的代码正在使用指向非托管缓冲区指针的悬挂指针。这是非常危险的,如果做得不好(如本例),将导致未定义的行为。由此产生的行为取决于所讨论的内存是否恰好在其间被重用于其他目的,这可能会导致不可预测的行为,这些行为会根据完全不相关的因素(例如循环计数或其他)而改变。

您应该尝试 运行 您的应用并打开 "address sanitizer"(在 "run" 设置下的方案设置中找到,在诊断选项卡上)它可能会报告一些这些问题。例如。当我 运行 你的代码带有地址清理器时,它报告:

==15249==ERROR: AddressSanitizer: heap-use-after-free on address 0x60300003a458 at pc 0x00010ba3bde6 bp 0x70000e837880 sp 0x70000e837028

有关详细信息,请参阅 Address Sanitizer documentation or its introductory video

最简单的解决方案是消除 char * 并使用 int 索引值或使用对象,例如 NSString *.