objective-c - 错误 : 'archiver has finished; cannot encode anything more'

标签 objective-c ios cocoa-touch uiimage grand-central-dispatch

我打算如下所示下载和编码图像。

但是我收到错误 -[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/

相关文章:

ios - 暂停/播放按钮监听器

ios - 删除 Uitableviewcontroller 上托管的 Uitableview 顶部或底部的 View ?

ios - 使用换行符附加 NSAttributedString 会返回格式错误的属性字符串

ios - Phonegap (Cordova) mailto 与 CC 的链接不起作用

iphone - 在 customtableviewcell 中加载并设置其 IBOUTLETS 时请求成员错误

iphone - 调用 setEditing 时自定义 UITableViewCell 调整大小标签

ios - 动画导航栏标题文本更改

ios - 相机图像选择器控件 - iOS7 中的自动旋转

ios - swift:将屏幕方向重置为纵向

objective-c - 当“重复次数”设置为"is"时,cheduledTimerWithTimeInterval仅触发一次