【问题标题】:Are objects modified when Archived/Unarchived?归档/取消归档时是否修改了对象?
【发布时间】:2014-04-27 19:57:45
【问题描述】:

所以这是我的问题。我正在尝试归档一个对象数组,当我取消归档它们时,尽管计数相同并且根对象内的对象相同,但它在未归档的数组中找不到指定的对象。

-(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 没有找到相同的对象,我在 SAME 函数中存档和取消存档却没有在数组中找到?归档和取消归档时是否修改了对象?还是我还缺少其他东西。

编辑:这是我的 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

【问题讨论】:

  • 什么样的对象是“供应商”?你在那个对象中实现了isEqual: 吗?

标签: ios arrays nskeyedarchiver


【解决方案1】:

这意味着找不到对象2147483647 == NSNotFound

您要做的是保存一组对象,然后将它们读回一个变量。这样做将再次创建 (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 了解更多信息。

【讨论】:

  • 这可能是两个答案中最有益的。我认为最好在你的答案中包括为什么它们不是完全相同的对象(分配了一个新的内存位置,就像 Jesse 指出的那样。)
  • @Scott 可以,但你关心它们不在同一个内存地址吗?从同样的想法来看,它们是同一个对象吗?尽管我在回答中说过“它们不会是同一个对象”,但我的意思是它们不会占用同一个内存块。在那里回答我自己的问题!
  • 不,没关系。无论如何,它都被归档了,所以当它被取消归档时,每个对象很可能会位于不同的内存地址——只需要匹配 itemKey。至于“同一个对象”,对我来说还不是很清楚。 :D
【解决方案2】:

indexOfObject: 使用isEqual: 测试数组中的对象是否与您要查找的对象“相同”。当您归档和取消归档一个对象时,生成的对象不在同一个内存地址(它实际上是原始对象的副本)。

由于 isEqual: 的默认实现仅针对同一对象(内存地址)返回 YES,这解释了您所看到的行为。你可能想要覆盖isEqual:(和hash,如果你覆盖isEqual:,你通常应该覆盖它)来检查任何成员变量对你的平等概念很重要。 (或者您可以使用无数个库中的一个来简化此操作,例如 Mantle。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多