Почему encodeWithCoder не вызывается в подклассе SKNode во время сохранения состояния приложения?

Резюме: когда я получаю пользовательский класс от родителя <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 все равно не вызывается в моем пользовательском классе.

(Детали моей реальной проблемы, которая вдохновила меня на этот тестовый пример, не кажутся уместными.)


person Karl Voskuil    schedule 12.05.2014    source источник
comment
Я ответил, что это потому, что SKNode не реализует NSCoding. Карл заметил (правильно): Хорошая мысль, но SKNode действительно реализует NSCoding (см. SKNode Справочник по классам). Кроме того, способ обработки сообщений работает, даже если MyNode не объявил, что он соответствует <NSCode>, он все равно попытается обработать сообщение encodeWithCoder. Я удалил свой ответ, потому что люди могут игнорировать вопрос, поскольку на него уже есть ответ.   -  person vacawama    schedule 13.05.2014
comment
Как бы то ни было, я работаю над новым приложением и сталкиваюсь с той же проблемой, и она до сих пор не дает мне покоя: что происходит в NSKeyedArchiver encodeObject:forKey:, что может помешать вызову метода encodeWithCoder: объекта, и что SKNode делает для предотвращения такого вещь? Ответ должен быть в исходном коде.   -  person Karl Voskuil    schedule 10.03.2016