3

我有一个“doesNotRecognizeSelector”异常,我怀疑我的 unarchiver 可能返回不可变数组而不是可变数组。我对吗 ?我应该如何正确归档和归档?(异常的地方显示出来)

谢谢!!!

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;
}
4

3 回答 3

6

NSKeyedUnarchiver确实返回一个不可变的NSArray. 如果你真的想得到一个NSMutableArray,你需要调用-mutableCopyfrom 的返回值decodeObjectForKey:

这个代码片段让我想知道你是否真的需要一个可变数组。看起来您只是对从中获得的数组进行排序-read。为什么不直接调用sortedArrayUsingSelector:不可变的 NSArray 呢?

于 2010-12-21T16:00:23.913 回答
3

您已经将一个不可变数组传递给归档程序,那么您为什么希望取消归档程序返回一个可变数组呢?

如果您希望副本是可变的,那么您必须使用

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

作为

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

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

编辑:刚刚在 iOS 5.0 模拟器上使用 NSKeyedArchiver 进行了测试:

// 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 引起的,而归档和取消归档会保持实例的正确可变性属性!

于 2011-12-09T12:46:39.587 回答
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;
}
于 2015-01-23T14:26:36.377 回答