调试 NSOperationQueue 阻塞

发布于 2024-10-22 08:08:24 字数 1172 浏览 5 评论 0原文

我需要一些关于如何调试 10.6 版本下的 Cocoa 并发问题的指导。我正在将“for”循环转换为使用 NSOperations,但大多数时候,代码只是在循环的某个时刻冻结。我可以在控制台中看到 NSLog 输出。在极少数情况下,代码会一直运行,这样就没有问题。

该代码仅是模型层的,由控制器中的方法启动。该方法仅循环访问 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];
    }];
}

我做了很多 NSLog,这会是问题吗?来自后台线程的 NSLog'ing 是一件坏事吗?

由于我从块内添加到可变数组,因此将可变数组声明为 __block 是否正确?我已经尝试了两种方法,似乎与这个冻结问题没有什么区别。

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

谢谢

I need some guidance in how to debug problems with concurrency in Cocoa under 10.6. I'm converting a 'for' loop to use NSOperations but most of the time, the code just freezes at some point through the loop. I can see NSLog output in the console to that effect. On the rare occasion, the code will run all the way through and it's fine.

The code is model-layer only, initiated from a method in the controller. The method loops through just 8-10 model objects, instructing them to each write their output to a uniquely named file. 8 model objects = 8 separate files. There are no calls up to the GUI and the model objects are NSManagedObject subclasses, which contain a set of child NSManagedObject objects (0..n of them), which each owning object summarizes and writes out. The output format is JSON.

Code:

__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];
    }];
}

I do a lot of NSLogs, would that be the issue? Is NSLog'ing from background threads a bad thing?

Since I'm adding to the mutable array from withinside a block, is it correct that I declare the mutable array as __block? I've tried it both ways and seemingly no difference relating to this freezing problem.

How do I debug this problem using Xcode v4? I want to know the line of code that it's freezing on, or what two lines of code are executing at the same time and causing it to block the execution.. My former techniques of setting a single breakpoint and stepping through the code no longer work, because of the concurrency.

thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奈何桥上唱咆哮 2024-10-29 08:08:24

这与您的块范围变量无关。您的问题是, NSMutableArrayNSManagedObject 都不是以任何方式、形状或形式线程安全的。你不能做你在这里做的事。如果你想在主线程之外处理这个问题,你需要使用调度队列或类似的东西来串行处理每个项目(即使你回到主线程,你也应该在读取之前使用相同的队列)然而,在完成后将可变数组复制到不可变版本,然后使用新的不可变数组向主线程发送通知或回调可能会更容易、更安全。复制嵌入。

It's nothing to do with your block-scoped variable. Your problem is that neither NSMutableArray nor NSManagedObject are in any way, shape or form thread-safe. You cannot do what you're doing here. If you want to have this processed off the main thread, you need to use a dispatch queue or something similar to process each item serially (and even when you're back on the main thread, you should use that same queue before you read from your mutable array. It'd probably be easier and safer, however, to do something like copy the mutable array to an immutable version when you're finished and then dispatch a notification or call-back to the main thread with the new, immutable copy embedded.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文