错误:'存档已完成;无法编码更多内容

发布于 2024-12-13 05:49:51 字数 1180 浏览 0 评论 0原文

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

但是我收到错误 -[NSKeyedArchiverencodeObject:forKey:]: archiver has finish;无法编码更多内容”。谁能解释为什么会出现此错误以及如何解决它?

- (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)

I am intending to download and encode an image as shown below.

However I am getting the error -[NSKeyedArchiver encodeObject:forKey:]: archiver has finished; cannot encode anything more'. Can anyone explain why this error occurred and how I can I resolve it?

- (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"];
            });

        });
}

Error Stack

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小兔几 2024-12-20 05:49:51

您不应在 -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: 方法的外部,即在执行归档之前图像应该完全可用。

You should not use an asynchronous method in -encodeWithCoder:. The reason is simple. The function is usually called like this (in the lower level):

NSKeyedArchiver* archiver = [NSKeyedArchiver initForWritingWithMutableData:...];
...
[archiver encodeObject:yourObject forKey:@"key"];  // A
// ^ this calls [yourObject encodeWithCoder:archiver]
...
[archiver finishEncoding];   // B

Your -encodeWithCoder: is asynchronous with GCD. Therefore line A will return before anything happens, and then line B will be executed (still your scheduled function will not be called). This finish the archiver and prevents further encoding on it.

Later, the asynchronous method is allowed to start, and you download the image and convert it into PNG etc... and finally tell the encoder to -encodeObject:forKey. But this is already too late --- the archiver has already been finished long time before! Therefore the exception is thrown.

To avoid this, you should ensure not to call -encodeObject:forKey asynchronously. The GCD codes should be put outside of the -encodeWithCoder: method, i.e. the image should be completely available before performing the archiving.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文