Вы не должны использовать асинхронный метод в -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:
, т. Е. Изображение должно быть полностью доступно до выполнения архивирования.