2011-03-16 74 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