2010-12-21 28 views
3

我有一个“doesNotRecognizeSelector”异常,我怀疑也许我的unarchiver返回不可变数组intstead intstead。 我对不对?我应该如何正确进行归档和归档? (例外的地方显示)存档可变阵列 - doesNotRecognizeSelector异常

谢谢!

NSMutableArray* arr; 

- (void) write 
{ 
     NSMutableData *data = [[NSMutableData alloc] init]; 
     NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 

NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] copy]; 
     [archiver encodeObject:copy forKey:@"Key"]; 
     [archiver finishEncoding]; 
     [data writeToFile:[Util DataPath] atomically:YES]; 
     [archiver release]; 
     [data release]; 
     [copyOfPaidPacks release]; 
} 




-(NSMutableArray*) read 
{ 
    NSString* DataPath = [Util FilePath]; 
    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:DataPath]; 
    NSKeyedUnarchiver *unarchiver = nil; 
    if (data != nil) 
    { 
      unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data]; 

    if([self.Arr count] <= 0) 
    { 
     self.Arr = [unarchiver decodeObjectForKey:@"Key"]; 
    } 
} 

[unarchiver finishDecoding]; 
[unarchiver release]; 
[data release]; 
    return self.arr 
} 

-(void)B 
{ 
    [self write]; 
    NSMutableArray* SecondArr = [self read]; 
    [SecondArr sortUsingSelector:@selector(CompareDate:)]; - > `****THIS IS WHERE I GET THE EXCEPTION` 
} 
  • 编辑

添加比较方法:

- (NSComparisonResult)CompareDate:(T*)p 
{ 
    NSComparisonResult result = [self.changeDate compare:p.changeDate]; 
    if(result == NSOrderedDescending) 
     result = NSOrderedAscending; 
    else if(result == NSOrderedAscending) 
     result = NSOrderedDescending; 

    if(result == NSOrderedSame) 
    { 
     result = [self CompareName:p]; 
    } 

    return result; 
} 
+0

什么是选择它不承认?编辑:好吧,向下滚动,看看现在。你有没有定义一个自定义的`CompareDate:`方法?另外,你的数组中有什么样的对象? – NSGod 2010-12-21 16:07:23

+0

我确定了它。我添加了代码,以便您查看它。 – Idan 2010-12-21 20:55:19

回答

6

NSKeyedUnarchiver确实返回一个不可变NSArray。如果您确实想获得NSMutableArray,则需要致电-mutableCopy,获取decodeObjectForKey:的返回值。

这段代码让我怀疑你是否真的需要一个可变数组。看起来你只是对从-read得到的数组进行排序。为什么不直接在不可变的NSArray上调用sortedArrayUsingSelector:呢?

3

您已经将不可变数组传递给存档器,那么为什么您会期望unarchiver返回一个可变的数组呢?

如果你要一个副本是可变的,那么你必须使用

NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] mutableCopy]; 

NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] copy]; 

将(至少就创建一个不变的副本,你应该予以关注。实际上,框架通常会为不可变实例使用可变内部表示,但这是一个实现细节,您不应该依赖它,因为这些表示在过去发生了变化,并且Cocoa文档明确告诉您不检查内部表示)。

编辑: 只需用的NSKeyedArchiver测试自己在iOS 5.0模拟器:

// this returns a mutable instance at runtime! 
NSMutableArray* test0 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[NSMutableArray array]]]; 
// this returns an immutable instance at runtime! 
NSArray* test1 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:[NSArray array]]]; 

所以你的问题真的仅仅通过复制而不是mutableCopy引起的,而封存和解除封存保留的正确的易变性的属性实例!

0

我有一个问题,即归档一个3维可变数组(即,可变数组的可变数组的可变数组)将作为不可变数组的不可变数组的可变数组解决。

的关键,固定,这是子类NSKeyedUnarchiver并覆盖

- (Class)classForClassName:(NSString *)codedName 
{ 
    Class theClass = [super classForClassName: codeName]; 

    if ([codeName isEqualToString: NSStringFromClass(NSArray.class)) 
    { 
     theClass = NSMutableArray.class; 
    } 
    //... more here like NSDictionary 
    return theClass; 
}