Резюме: когда я получаю пользовательский класс от родителя <NSCoding>
, я вижу, что мой метод encodeWithCoder
вызывается во время сохранения состояния приложения. Если я изменю своего родителя на SKNode
, мой метод encodeWithCoder
больше не будет вызываться.
Подробности:
Мой контроллер представления кодируется во время сохранения состояния приложения UIKit
. Он кодирует один объект типа MyNode
.
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
[super encodeRestorableStateWithCoder:coder];
MyNode *myNode = [[MyNode alloc] init];
NSLog(@"view controller encoding");
[coder encodeObject:myNode forKey:@"myNode"];
}
MyNode
— это урезанный класс, созданный для этого вопроса. Я включу код для полноты картины, но методы кодирования и декодирования просто вызывают NSLog
и super
.
@interface MyParent : NSObject <NSCoding>
@end
@interface MyNode : MyParent
@end
@implementation MyParent
- (id)initWithCoder:(NSCoder *)aDecoder
{
NSLog(@"MyParent decoding");
self = [super init];
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
NSLog(@"MyParent encoding");
}
@end
@implementation MyNode
- (id)initWithCoder:(NSCoder *)aDecoder
{
NSLog(@"MyNode decoding");
self = [super initWithCoder:aDecoder];
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
NSLog(@"MyNode encoding");
[super encodeWithCoder:aCoder];
}
@end
Когда родителем MyNode
является MyParent
, как написано выше, я вижу свой зарегистрированный вывод во время сохранения приложения:
2014-05-12 15:22:33.342 Flippy[35091:60b] saving application state
2014-05-12 15:22:33.342 Flippy[35091:60b] view controller encoding
2014-05-12 15:22:33.343 Flippy[35091:60b] MyNode encoding
2014-05-12 15:22:33.343 Flippy[35091:60b] MyParent encoding
Но когда я меняю родителя MyNode
на SKNode
, мои реализации encodeWithCoder
не вызываются:
2014-05-12 15:22:57.847 Flippy[35115:60b] saving application state
2014-05-12 15:22:57.848 Flippy[35115:60b] view controller encoding
Почему нет?
Что я пробовал:
- Архивирование моего пользовательского класса с использованием моего собственного файла
NSKeyedArchiver
. Это работает, как и ожидалось. - Реализация протокола
UIStateRestoring
в моем пользовательском классе и его регистрация в приложении с идентификатором восстановления. Это не имело большого смысла для меня. - Возиться с
classForCoder
, как в этом вопросе . Но это не похоже на то, что это применимо, иclassForCoder
все равно не вызывается в моем пользовательском классе.
(Детали моей реальной проблемы, которая вдохновила меня на этот тестовый пример, не кажутся уместными.)
SKNode
не реализуетNSCoding
. Карл заметил (правильно): Хорошая мысль, ноSKNode
действительно реализуетNSCoding
(см.SKNode
Справочник по классам). Кроме того, способ обработки сообщений работает, даже еслиMyNode
не объявил, что он соответствует<NSCode>
, он все равно попытается обработать сообщениеencodeWithCoder
. Я удалил свой ответ, потому что люди могут игнорировать вопрос, поскольку на него уже есть ответ. - person vacawama   schedule 13.05.2014NSKeyedArchiver encodeObject:forKey:
, что может помешать вызову методаencodeWithCoder:
объекта, и чтоSKNode
делает для предотвращения такого вещь? Ответ должен быть в исходном коде. - person Karl Voskuil   schedule 10.03.2016