我有一个“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;
}
答案 0 :(得分:6)
NSKeyedUnarchiver
确实会返回一个不可变的NSArray
。如果您真的想获得NSMutableArray
,则需要在-mutableCopy
的返回值上调用decodeObjectForKey:
。
这段代码让我想知道你是否真的需要一个可变数组。看起来您只是对从-read
获得的数组进行排序。为什么不在不可变的NSArray上调用sortedArrayUsingSelector:
呢?
答案 1 :(得分:3)
你已经将一个不可变数组传递给了归档器,那你为什么期望unarchiver返回一个可变数组呢?
如果您希望副本可变,则必须使用
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]]];
所以你的问题实际上是由使用copy而不是mutableCopy引起的,而归档和unarchiving保留了实例的正确可变性属性!
答案 2 :(得分:0)
我有一个问题,即归档一个三维可变数组(即可变数组的可变数组的可变数组)将作为不可变数组的不可变数组的可变数组进行归档。
解决这个问题的关键是继承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;
}