Вопрос по ios, inheritance, objective-c – Сохранение NSArray пользовательских объектов

2

Я создал подкласс UIImage (UIImageExtra), так как я хочу включить дополнительные свойства и методы.

У меня есть массив, который содержит экземпляры этого пользовательского класса. Однако, когда я сохраняю массив, кажется, что дополнительные данные в классе UIImageExtra не сохраняются.

UIImageExtra соответствует NSCoding, но ни initWithCoder, ни encodeWithCoder не вызываются, поскольку добавленные мной операторы NSLog не печатаются.

Мой метод сохранения массива выглядит так:

- (void)saveIllustrations {
if (_illustrations == nil) {
    NSLog(@"Nil array");
    return;
}

[self createDataPath];
//Serialize the data and write to disk
NSString *illustrationsArrayPath = [_docPath stringByAppendingPathComponent:kIllustrationsFile];
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:_illustrations forKey:kIllustrationDataKey];
[archiver finishEncoding];
[data writeToFile:illustrationsArrayPath atomically: YES];
}

И UIImageExtra имеет следующие методы делегата для сохранения:

    #pragma mark - NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder {
    NSLog(@"Encoding origin data!");
    [super encodeWithCoder:aCoder];
    [aCoder encodeObject:originData forKey:kOriginData];
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:(NSCoder *) aDecoder]) {
        NSLog(@"Decoding origin data");
        self.originData = [aDecoder decodeObjectForKey:kOriginData];
    }
    return self;
}

Мой код для создания массива в первую очередь выглядит следующим образом (в случае, если предлагает какие-либо подсказки)

        for (NSDictionary *illustrationDict in illustrationDicts) {
        NSString *illustrationString = [illustrationDict objectForKey:@"Filename"];
        NSNumber *xCoord = [illustrationDict objectForKey:@"xCoord"];
        NSNumber *yCoord = [illustrationDict objectForKey:@"yCoord"];
        UIImageExtra *illustration = (UIImageExtra *)[UIImage imageNamed:illustrationString];

        //Scale the illustration to size it for different devices
        UIImageExtra *scaledIllustration = [illustration adjustForResolution];
        NSValue *originData = [NSValue valueWithCGPoint:CGPointMake([xCoord intValue], [yCoord intValue])];
        [scaledIllustration setOriginData:originData];
        [self.illustrations addObject:scaledIllustration];
    }

Или я просто собираюсь сохранить эти данные неправильно? Большое спасибо.

Ваш Ответ

2   ответа
3

его подкласса UIImageExtra.

UIImageExtra *illustration = (UIImageExtra *)[UIImage imageNamed:illustrationString];

возвращает UIImage. Актерство не делает то, что вы намеревались.

UIImageExtra *scaledIllustration = [illustration adjustForResolution];

являетсяstill просто UIImage.

Один простой, но многословный способ сделать это - сделать UIImageExtrawrapper вокруг UIImage. Оболочка будет иметь метод класса для инициализации из UIImage:

+ (UIImageExtra)imageExtraWithUIImage:(UIImage *)image;

И затем каждый метод UIImage, который вы хотите вызвать, должен был бы перенаправить в обернутый экземпляр UIImage - также будьте осторожны, чтобы повторно обернуть результат, например.-adjustForResolution чтобы вы снова не получили развернутый экземпляр UIImage.

Более сложным подходом Objective-C было бы добавить функциональность, которую вы хотите вCategory на UIImage, а затем использоватьmethod swizzling заменить методы NSCoding вашими реализациями категории. Сложная часть этого (кроме требуемой гимнастики во время выполнения Objective-C) - где хранить ваши "дополнительные" данные, поскольку вы не можете добавлять переменные экземпляра в категорию. [Стандартный ответ состоит в том, чтобы иметь словарь в стороне, снабженный ключом некоторым подходящим представлением экземпляра UIImage (например, NSValue, содержащим его значение указателя), но, как вы можете себе представить, бухгалтерия может быстро усложниться.]

Остановившись на секунду, я бы посоветовал новому программисту Cocoa: «Подумайте о более простом способе». Если то, что вы пытаетесь сделать, это сложно, попробуйте что-нибудь другое. & Quot; Например, напишите простойImageValue класс, который имеет-image метод и-extraInfo метод (и реализует NSCoding и т. д.), и сохраните экземпляры этого в вашем массиве.

Я не совсем уверен, что входит в + (UIImageExtra *) imageExtraWithUIImage: (UIImage *) image; Что мне делать с аргументом UIImage? Я предполагаю, что я создаю новый объект UIImageExtra с помощью alloc и init и возвращаю его, но должен ли я установить UIImage как свойство этого недавно выделенного UIImageExtra? В каком случае я должен определить экземпляр UIImage в подклассе? Странно ли иметь экземпляр родительского класса в качестве свойства его подкласса? Или я могу как-то установить родительский класс в качестве экземпляра UIImage? Smikey
1

ableArray, это может быть проблемой.

Похожие вопросы