Преобразование NSObject в NSData - PullRequest
15 голосов
/ 02 ноября 2009

У меня проблема с преобразованием NSObject в NSData. У меня есть класс, который наследует NSObject.

Когда я пытался преобразовать объект этого конкретного класса в NSData следующим образом:

NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:classObject];

но выдает исключение, сообщающее, что -[classObject encodeWithCoder:]: нераспознанный селектор отправлен в экземпляр ..

Я также добавил объект во вновь созданный массив как

NSMutableArray *wrapperedData = [NSMutableArray arrayWithObject: classObject];
NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:value];

Но, тем не менее, это исключение.

Так что мне нужно извлечь байты из объекта classObject.

Любая помощь будет принята с благодарностью ...

в ожидании вашего ответа ...

Ответы [ 6 ]

22 голосов
/ 01 августа 2013

Вы должны реализовать свой собственный объект, такой как:

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeInt:self.age forKey:@"age"];
    [aCoder encodeObject:self.email forKey:@"email"];
    [aCoder encodeObject:self.password forKey:@"password"];
}
BOOL success = [NSKeyedArchiver archiveRootObject:person toFile:archiveFilePath];

и

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeIntForKey:@"age"];
        self.email = [aDecoder decodeObjectForKey:@"email"];
        self.password = [aDecoder decodeObjectForKey:@"password"];
    }
    return self;
}
Person *unarchivePerson = [NSKeyedUnarchiver unarchiveObjectWithFile:archiveFilePath];
7 голосов
/ 02 ноября 2009

Вам необходимо реализовать encodeWithCoder: в вашем пользовательском классе, сериализовав все его атрибуты, используя переданный в него NSCoder. Если его атрибуты включают какие-либо дополнительные пользовательские классы, им также понадобится encodeWithCoder: реализовать.

6 голосов
/ 20 сентября 2010

вместо

NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:classObject];

должно быть

NSData *dataOnObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"someKey"];

Но это только для чтения данных, которые уже были сохранены. Если вы хотите сохранить объект как NSData, у вас есть это:

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:classObject] forKey:@"someKey"];

Но это еще не все. Ваш classObject должен реализовать протокол NSCoding и иметь два метода encodeWithCoder: и initWithCoder: так как это не объект NS, чтобы он работал.

5 голосов
/ 02 ноября 2009

вы можете архивировать только те объекты, которые поддерживают протокол NSCoding

1 голос
/ 08 мая 2012

Вы можете преобразовать любой объект в NSData с помощью протокола NSCoding.

Пример кода для этого можно найти здесь:
http://samsoff.es/posts/archiving-objective-c-objects-with-nscoding

0 голосов
/ 17 февраля 2016

Это пример пользовательского объекта, преобразованного в NSData (поэтому его можно сохранить в пользовательские настройки по умолчанию)

Создайте следующие файлы:

Catalog.h

@interface Catalog : NSObject

@property (nonatomic, assign) int pk;
@property (nonatomic, copy) NSString *catalogName;
@property (nonatomic, copy) NSString *catalogDescription;
@property (nonatomic, assign) int catalogEdition;
@property (nonatomic, assign) int catalogTotalPages;

- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;

@end

Catalog.m

#import <Foundation/Foundation.h>
#import "Catalog.h"

@implementation Catalog

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.catalogName forKey:@"catalogName"];
    [aCoder encodeObject:self.catalogDescription forKey:@"catalogDescription"];
    [aCoder encodeInt:self.catalogEdition forKey:@"catalogEdition"];
    [aCoder encodeInt:self.catalogTotalPages forKey:@"catalogTotalPages"];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        self.catalogName = [aDecoder decodeObjectForKey:@"catalogName"];
        self.catalogDescription = [aDecoder decodeObjectForKey:@"catalogDescription"];
        self.catalogEdition = [aDecoder decodeIntForKey:@"catalogEdition"];
        self.catalogTotalPages = [aDecoder decodeIntForKey:@"catalogTotalPages"];
    }
    return self;
}

@end

Наконец, в вашем контроллере есть заголовочные файлы

#import "Catalog.h"

И добавьте этот код для использования вашего объекта (в этом случае я сохраняю его в пользовательские настройки по умолчанию)

            Catalog *catalog = [[Catalog alloc] init];
            catalog.catalogName = @"catalogName";
            catalog.catalogDescription = @"catalogName";
            catalog.catalogEdition = 1;

ПРИМЕЧАНИЕ: в этой строке кода происходит фактическая передача данных

//archiving object to nsdata
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:catalog];

[[NSUserDefaults standardUserDefaults] setObject:encodedObject forKey:@"keyName"];
[[NSUserDefaults standardUserDefaults] synchronize];

В случае, если вы хотите вернуть свой объект из NSData

NSData *nsData = [[NSUserDefaults standardUserDefaults] objectForKey:@"keyName"];
//unarchiving object to nsdata
Catalog *selectedCatalog = [NSKeyedUnarchiver unarchiveObjectWithData: nsData];

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...