0
我試圖從背景線程上的文本文件中加載數據,該數據包含一個完成處理程序,它會在使用常規處理數據後寫出一個plist表達。我收到「集合被枚舉時發生了變化」的錯誤,但我不確定爲什麼它會在這種情況下拋出。我正在使用塊和後臺線程。所以,我認爲我做了一個邏輯錯誤,但我不明白爲什麼:處理後臺線程時出現「收集變異......」的異常情況
- 的可變數組的計數是在破發點(發生錯誤)
- 不一致在一個點上,過程中沒有完成正確(填充data.plist文件)
- 當我試圖在歸檔之前使用可變數組的副本時,I 會收到「試圖插入nil對象」錯誤,但原始nsmutablearray計數在此時似乎有效(看更新)
東西有趣的是,由於不一致的計數和(一次性)成功完成,我認爲我的後臺處理可能是罪魁禍首。
這裏的一個局部的DataManager類的init方法的:
if (!abcMutableArray)
abcMutableArray = [[NSMutableArray alloc] init];
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the plist file doesn't exist in the Documents Folder, create it from the text file
if (![fileManager fileExistsAtPath:[self filePath]]) {
[self createDataFile];
}
這裏是輔助方法
- (void) createDataFile
{
__weak DataManager* weakSelf = self;
[weakSelf loadData:^(BOOL completed){
if(completed)
{
//Next line produces **Collection <__NSArrayM: 0x8fa28c0> was mutated while being enumerated**
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:[weakSelf abcMutableArray]];
[data writeToFile:[weakSelf filePath] atomically:YES];
}
}];
}
此方法執行負載,完成後,通過完成回調給來電者
- (void) loadData:(void (^)(BOOL))completed
{
__weak DataManager* weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSError *localError = NULL;
NSStringEncoding fileEncoding = NSUTF8StringEncoding;
NSURL* fileURL = [[NSBundle mainBundle] URLForResource:@"data" withExtension:@"txt"];
NSString* fh= [NSString stringWithContentsOfURL:fileURL usedEncoding:&fileEncoding error:&localError];
for (NSString *line in [fh componentsSeparatedByString:@"\n"]) {
if (![line hasPrefix:@"#"])
{
// [self parseLine:line];
//parsing routine
NSError *error = NULL;
Thing* t = [[Thing alloc]init];
NSString* pattern = @"(^.*)\\s(.*)\\s\\[(.*)\\]\\s\\/(.*)\\;\\s(.*)";
NSRegularExpression *regEx = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regEx matchesInString:line
options:0
range:NSMakeRange(0, [line length])];
for (NSTextCheckingResult *match in matches) {
if ([match numberOfRanges] == 6) {
//The range at index 0 contains the entire string.
thing.a = (NSString*)[line substringWithRange:[match rangeAtIndex:1]];
thing.b = (NSString*)[line substringWithRange:[match rangeAtIndex:2]];
thing.c = (NSString*)[line substringWithRange:[match rangeAtIndex:3]];
thing.d = (NSString*)[line substringWithRange:[match rangeAtIndex:4]];
thing.e = (NSString*)[[[line substringWithRange:[match rangeAtIndex:5]]stringByReplacingOccurrencesOfString:@"/" withString:@". "] stringByReplacingOccurrencesOfString:@".." withString:@"."];
[[weakSelf abcMutableArray] addObject:thing];
} //end-if match
} //end-for matches
} //end-if line
} //end-for lines
//file load data process is completed
completed(YES);
});
}
更新
當試圖複製方法添加到代碼的建議:
NSData* data = [NSKeyedArchiver archivedDataWithRootObject:[[weakSelf abcMutableArray]copy]];
我在同樣的破發點以下錯誤。
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[12]'
注比我在NSData的線突破我可以看到abcMutableArray包含可變數量的對象(每個週期中不同的對象,這使我相信,我的後臺線程尚未完成處理)。
好建議然而,當重複測試時,這有時會拋出***由於未捕獲的異常'NSInvalidArgumentException',原因:'*** - [__ NSPlaceholderArray initWithObjects:count:]嘗試從對象插入nil對象[ 2443]'|我的測試步驟是執行,請參閱data.plist,刪除data.plist,執行|想知道我的後臺任務有時不完整? –
我最終使用這種方法,我確定我的其他問題與線程相關。 –