Изменяются ли объекты при архивировании / разархивировании?

Итак, вот моя проблема. Я пытаюсь заархивировать массив объектов, и когда я разархивирую их, хотя их количество одинаковое, а объекты внутри корневого объекта одинаковы, он не находит указанный объект в неархивированном массиве.

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"self.vendors.count = %d", self.vendors.count);
    [NSKeyedArchiver archiveRootObject:self.vendors toFile:[self vendorsArchivePath]];

    NSMutableArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:[self
                                vendorsArchivePath]];
    NSLog(@"array.count = %d", array.count);
    NSLog(@"%d", [self.vendors indexOfObject:self.vendors[indexPath.row]]);
    NSLog(@"%d", [array indexOfObject:self.vendors[indexPath.row]]);
}

Для устранения неполадок в себе; У меня есть счетчики обоих массивов в списке и в нижней части и индекс объекта в каждом массиве в NSLog.

Вот журнал...

2014-04-27 12:53:04.813 Inventory[12272:907] self.vendors.count = 5
2014-04-27 12:53:04.827 Inventory[12272:907] array.count = 5
2014-04-27 12:53:04.828 Inventory[12272:907] 0
2014-04-27 12:53:04.831 Inventory[12272:907] 2147483647

Итак, мой вопрос: почему в мире последний NSLog не может найти тот же объект, который я заархивировал и разархивировал в той же функции, а не в массиве? Изменяются ли объекты при архивации и разархивировании? Или я что-то пропустил?

РЕДАКТИРОВАТЬ: Вот мои файлы vendor.h и vendor.m:

//vendor.h
#import <Foundation/Foundation.h>

@interface SELVendor : NSObject <NSCoding>

@property (nonatomic) NSMutableArray *itemsAvailable;
@property (nonatomic) NSString *name;
@property (nonatomic) NSString *phoneNumber;
@property (nonatomic) NSString *email;
@property (nonatomic) NSString *vendorKey;

@end

//vendor.m
#import "SELVendor.h"

@implementation SELVendor

-(instancetype) init {
    self = [super init];
    if (self) {
        self.name = @"Unnamed Vendor";
        self.itemsAvailable = [[NSMutableArray alloc] init];

        NSUUID *uuid = [[NSUUID alloc] init];
        self.vendorKey = [uuid UUIDString];
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.itemsAvailable forKey:@"itemsAvailable"];
    [aCoder encodeObject:self.phoneNumber forKey:@"phoneNumber"];
    [aCoder encodeObject:self.email forKey:@"email"];
    [aCoder encodeObject:self.vendorKey forKey:@"vendorKey"];
}

-(instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.itemsAvailable = [aDecoder decodeObjectForKey:@"itemsAvailable"];
        self.phoneNumber = [aDecoder decodeObjectForKey:@"phoneNumber"];
        self.email = [aDecoder decodeObjectForKey:@"email"];
        self.vendorKey = [aDecoder decodeObjectForKey:@"vendorKey"];
    }
    return self;
}

@end

2 ответа

Решение

Это означает, что объект не был найден 2147483647 == NSNotFound

То, что вы пытаетесь сделать, это сохранить массив объектов, а затем прочитать их обратно в varaible. Делая это создаст (alloc/init) объекты снова, чтобы они не занимали одно и то же место в памяти. В зависимости от того, как вы реализуете свои методы кодирования / декодирования, объект может быть точно таким же, как и другой (по содержанию). Что вам нужно сделать, это переопределить isEqual: (а также hash) в вашем классе и проверьте объекты там.

Если у вас есть объекты какие-то ID свойство, которое вы можете просто сделать:

-(BOOL)isEqual:(id)object
{
    if (self == object) {
        return YES;
    }
    if (![object isKindOfClass:[self class]]) {
        return NO;
    }
    return [self.ID isEqual:object.ID];
}

Если ни одно из ваших свойств на вашем объекте не является уникальным, вы можете проверить каждый из них в isEqual: метод.

Смотрите этот ответ для получения дополнительной информации.

indexOfObject: использования isEqual: проверить, является ли объект в массиве "таким же", как объект, который вы ищете. Когда вы архивируете и разархивируете объект, результирующий объект не находится на том же адресе памяти (это фактически копия исходного объекта).

Поскольку реализация по умолчанию isEqual: возвращайте YES только для того же объекта (адрес памяти), это объясняет поведение, которое вы видите. Вы, вероятно, хотите переопределить isEqual: (а также hash, который вы обычно должны переопределить, если вы переопределите isEqual:) проверить, какие переменные-члены важны для вашего понятия равенства. (Или вы можете использовать одну из множества библиотек, которые облегчают эту задачу, например, Mantle.)

Другие вопросы по тегам