我打算如下所示下载和编码图像。
但是我收到错误 -[NSKeyedArchiver encodeObject:forKey:]: archiver has finished;不能编码更多'。谁能解释为什么会出现此错误以及我该如何解决?
- (void)encodeWithCoder:(NSCoder *)encoder
{
dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL);
dispatch_async(downloadQueue, ^{
NSURL *url = [NSURL URLWithString:self.avatar_url];
NSData *data = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
self.avatar = [[[UIImage alloc] initWithData:data] autorelease];
[encoder encodeObject:UIImagePNGRepresentation(self.avatar) forKey:@"avatar"];
});
});
}
错误堆栈
2011-11-03 00:08:32.645 onethingaday[6897:207] *** Terminating app due to uncaught exception 'NSInvalidArchiveOperationException', reason: '*** -[NSKeyedArchiver encodeObject:forKey:]: archiver has finished; cannot encode anything more'
*** First throw call stack:
(0x29de052 0x26ddd0a 0x2986a78 0x29869e9 0x16e1d40 0x9fdd 0x1d33445 0x1d354f0 0x2915833 0x2914db4 0x2914ccb 0x2d57879 0x2d5793e 0xd89a9b 0x290d 0x2885 0x1)
最佳答案
您不应该在 -encodeWithCoder:
中使用异步方法。原因很简单。该函数通常这样调用(在较低级别):
NSKeyedArchiver* archiver = [NSKeyedArchiver initForWritingWithMutableData:...];
...
[archiver encodeObject:yourObject forKey:@"key"]; // A
// ^ this calls [yourObject encodeWithCoder:archiver]
...
[archiver finishEncoding]; // B
您的 -encodeWithCoder:
与 GCD 是异步的。因此,A 行将在任何事情发生之前返回,然后 B 行将被执行(仍然不会调用您的计划函数)。这完成了存档器并防止对其进行进一步编码。
稍后,允许启动异步方法,下载图像并将其转换为 PNG 等......最后告诉 encoder
-encodeObject:forKey
。但这已经太晚了——存档器早就完成了!因此抛出异常。
为避免这种情况,您应该确保不要异步调用-encodeObject:forKey
。 GCD 代码应该放在 -encodeWithCoder:
方法的外面,即在执行归档之前图像应该完全可用。
关于objective-c - 错误 : 'archiver has finished; cannot encode anything more' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7983703/