2011-03-16 41 views
0

我需要一些关于如何在10.6下调试Cocoa中的并发问题的指导。我将'for'循环转换为使用NSOperations,但大多数情况下,代码只是通过循环冻结。我可以在控制台中看到NSLog的输出。在极少数情况下,代码会一直运行,并且很好。调试NSOperationQueue阻塞

该代码仅为模型层,由控制器中的方法启动。该方法只循环8-10个模型对象,指示它们将每个输出写入一个唯一命名的文件。 8个模型对象= 8个单独的文件。没有调用直到GUI,模型对象是NSManagedObject子类,它包含一组子NSManagedObject对象(0..n),每个拥有对象进行汇总和写出。输出格式是JSON。

代码:

__block NSMutableArray *collectionOfCourses = [[NSMutableArray alloc] initWithCapacity:[[self courses] count]]; 

/* Create a filename. Use our title and set it to lowercase */ 
NSURL *ourFileURL = [aURL URLByAppendingPathComponent:[[self title] lowercaseString]]; 
ourFileURL = [ourFileURL URLByAppendingPathExtension:@"js"]; 

for (Course *aCourse in [self courses]) { 
     [[self opQueue] addOperationWithBlock:^{ 
     NSArray *arrayForOneCourse = [aCourse arrayAndWriteToFileURL:aURL fileFormat:format]; 
    [collectionOfCourses addObject:arrayForOneCourse]; 
    }]; 
} 

我做了很多NSLogs的,会是这样的问题? NSLog从后台线程是一件坏事?

由于我从一个块中添加到可变数组,是否正确,我声明可变数组为__block?我已经尝试了这两种方式,似乎没有关于这个冻结问题的差异。

如何使用Xcode v4调试此问题?我想知道它冻结的代码行,或者同时执行两行代码并导致它阻止执行。我以前设置单个断点并逐步完成代码的技术不再有效,因为并发性。

谢谢

回答

3

这与您的块范围变量没有任何关系。你的问题是,NSMutableArrayNSManagedObject都没有任何形式或形式线程安全。你不能做你在这里做的事情。如果您希望将此处理从主线程处理掉,则需要使用分派队列或类似的方法来串行处理每个项目(并且即使当您回到主线程时,也应该在读取之前使用同一个队列你的可变数组可能会更简单也更安全,但是,当你完成后,将可变数组复制到不可变的版本,然后用新的不可变的方法派发通知或回调主线程嵌入式复制

+0

重做并发布后续问题作为新文章http://stackoverflow.com/questions/5363312/how-to-ensure-tasks-have-completed – Woodster