NSOperationQueue方法参数变空

时间:2018-01-02 14:00:29

标签: objective-c objective-c-blocks nsoperationqueue nsoperation

我遇到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次,由于这个我无法执行其他操作。请帮我解决这个问题。

1 个答案:

答案 0 :(得分:1)

问题不在于NSOperationQueue。问题是使用char *。正如documentation for cStringUsingEncoding says

  

保证返回的C字符串仅在接收器被释放之前有效,或者直到当前存储器被清空为止,以先发生者为准。如果需要在此时间之后存储C字符串,则应复制C字符串或使用getCString:maxLength:encoding:

底线,像char *这样的简单C指针不参与(自动)引用计数。您的代码使用悬空指针指向非托管缓冲区指针。这非常危险,如果没有正确完成(如本例所示),将导致未定义的行为。由此产生的行为决定了所讨论的存储器是否恰好在中间时间内被重用于其他目的,这可能导致不可预测的行为,这种行为会根据完全不相关的因素(例如循环计数或其他因素)而发生变化。

您应该尝试使用&#34;地址清洁剂&#34;打开(在诊断选项卡上的&#34;运行&#34;设置下的方案设置中找到),它可能会报告其中一些问题。例如。当我使用地址清理程序运行您的代码时,它报告:

  

== 15249 ==错误:AddressSanitizer:地址为0x60300003a458,地址为0x000300003bde6 bp 0x70000e837880 sp 0x70000e837028

有关详细信息,请参阅Address Sanitizer documentation或其introductory video

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