Pergunta

So here is my problem. I am trying to archive an array of objects and when I unarchive them although the count is the same and the objects inside the root object are the same it does not find the specified object in the unarchived array.

-(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]]);
}

In order to troubleshoot myself; I have the counts of both arrays listed and at the bottom and the index of the object in each array in an NSLog.

Here is the log...

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

So my question is: Why in the world is the last NSLog not finding the same object, that I archived and unarchived in the SAME function not being found in the array? Are objects modified when archived and unarchived? Or is there something else that I am missing.

EDIT: Here are my vendor.h and vendor.m files:

//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
Foi útil?

Solução

This means that the object wasn't found 2147483647 == NSNotFound

What you're trying to do is save a array of objects, and then read them back out to a varaible. Doing this will create (alloc/init) the objects again so they won't occupy the same location in memory. Depending on how you implement your encoder/decode methods, the object might be exactly the same as the other one (content wise). What you need to do is override isEqual: (and hash) in your class and check the objects in there.

If you're objects have some kind of ID property you can just do:

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

If none of your properties on your object are unique, you can check each one in the isEqual: method.

See this answer for more info.

Outras dicas

indexOfObject: uses isEqual: to test whether an object in the array is the "same" as the object you're looking for. When you archive and unarchive an object, the resulting object is not at the same memory address (it is effectively a copy of the original object).

Since the default implementation of isEqual: return YES only for the same object (memory address), this explains the behavior you're seeing. You probably want to override isEqual: (and hash, which you should usually override if you override isEqual:) to check whatever member variables are important for your notion of equality. (Or you can use one of a zillion libraries out there that make this easier, such as Mantle.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top