繁体   English   中英

对于带有dispatch_async / GCD崩溃的循环

[英]For loops with dispatch_async / GCD crash

所以我试图了解GCD。 我有一个长期运行的操作,只是在下载后像这样追加数据:

        NSFileManager *fileManager = [NSFileManager defaultManager];
        __block NSFileHandle *output;
        output = [NSFileHandle fileHandleForUpdatingAtPath:tempPath];
        __block NSError *error = nil;
        BOOL success;
        dispatch_queue_t stitchQueue = dispatch_queue_create("com.test", NULL);

for (NSString *packetName in listOfFiles) {
           dispatch_async(stitchQueue, {
                NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
                NSString *packetPath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent:packetName];

            NSData *packetData = [[NSData alloc] initWithContentsOfFile:packetPath];

            [output seekToEndOfFile];
            [output writeData:packetData];

            [fileManager removeItemAtPath:packetPath error:&error];
            NSLog(@"Removed file after appending data success: %i Error: %@", success, [error localizedDescription]);
            [self updateManifestColumn:@"IsParsed" withValue:YES forFile:packetName inTable:tableName];

            packetData = nil;
            [packetData release];
            [pool release];
            });
        }
        [output closeFile];

// dispatch_async(//将数据缝合在一起后执行下一个长期运行的任务)

如果我删除dispatch_async调用,则此代码有效。 难道我做错了什么? 当我使用dispatch_async运行它时,它成功完成了一次迭代,然后崩溃了。 由于对NSFileHandle的访问不当而崩溃。 它似乎在1次迭代后被取消分配。 我不确定该如何解决。 谢谢!

崩溃是由__block说明符引起的。 通常,在该块的生存期内,将保留该块所使用的来自周围范围的每个对象变量。 这对于dispatch_asyncdispatch_after尤其有用,并且意味着只要块未完成,对象就将有效。 这是一眼看不到的真正力量。 但是,当您要更改对象指针或原始变量值时,需要使用__block说明符。 该说明符以不同的方式对待对象变量,并且不按块保留它们,因此允许在块完成之前将其释放。 这正是您正在发生的事情。 排队:

output = [NSFileHandle fileHandleForUpdatingAtPath:tempPath];

您正在创建将在不久的将来发布的自动发布对象。 由于您使用的是dispatch_async这可能会在块仍在运行时发生,从而导致崩溃。

有两种解决方案:

  • 您可以将本地变量设为类的实例变量,以延长该对象的寿命,

  • 但是最简单的方法是删除__block因为您无需在块内更改对象的指针,并且根本不需要此说明符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM