2014-04-27 4 views
2

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

-(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 не найти тот же объект, что я в архиве и разархивирована в одной функции не найден в массив? Изменены ли объекты при архивировании и распаковке? Или есть что-то еще, что мне не хватает.

EDIT: Вот мои vendor и 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 
+1

Какой объект является «продавцом»? Вы реализовали 'isEqual:' в этом объекте? –

ответ

3

Это означает, что объект не был найден 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:.

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

+0

Возможно, это был самый полезный из двух ответов. Я думаю, что было бы лучше включить в ваш ответ, почему они не совсем одни и те же объекты (присвоено новое местоположение памяти, как указывает Джесси.) – Scott

+0

@Scott будет делать, хотя вам все равно, что они не на такой же адрес памяти? И из этой же мысли они - один и тот же объект? Несмотря на то, что я сказал в своем ответе «они не будут одним и тем же объектом», я имел в виду, что они не будут занимать один и тот же блок памяти.Ответьте на мой вопрос! – Rich

+0

Нет, не имеет значения. Все это архивировано в любом случае, поэтому, скорее всего, каждый объект будет иметь другой адрес памяти, когда он будет распакован - просто нужно сопоставить itemKey. Что касается «того же объекта», это было не так ясно для меня. : D – Scott

2

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

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

Смежные вопросы