Iphone 存档可变数组-不可识别选择器异常
我有一个“doesNotRecognizeSelector”异常,我怀疑我的unarchiver可能返回不可变数组而不是可变数组。 我说得对吗?我应该如何正确地进行归档和归档?(例外位置显示在下方) 谢谢Iphone 存档可变数组-不可识别选择器异常,iphone,objective-c,cocoa-touch,immutability,archiving,Iphone,Objective C,Cocoa Touch,Immutability,Archiving,我有一个“doesNotRecognizeSelector”异常,我怀疑我的unarchiver可能返回不可变数组而不是可变数组。 我说得对吗?我应该如何正确地进行归档和归档?(例外位置显示在下方) 谢谢 NSMutableArray* arr; - (void) write { NSMutableData *data = [[NSMutableData alloc] init]; NSKeyedArchiver *archiver = [[NSKeyedA
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`
}
nskeyedunachiver
确实返回一个不可变的NSArray
。如果您确实想获取NSMutableArray
,则需要调用-mutableCopy
以获取decodeObjectForKey:
的返回值
这个代码片段让我怀疑您是否真的需要一个可变数组。看起来您只是在对从
-read
获取的数组进行排序。为什么不直接调用不可变NSArray上的sortedArrayUsingSelector:?您已经将一个不可变数组传递给了归档程序,那么为什么您希望不归档程序返回一个可变数组呢
如果您希望副本是可变的,那么必须使用
NSMutableArray *copy = [[NSMutableArray arrayWithArray:self.Arr] mutableCopy];
作为
将创建一个不可变的副本(至少在您应该关注的范围内。实际上,框架通常会对不可变的实例使用可变的内部表示,但这是一个实现细节,您不应该依赖它,因为这些表示在过去已经更改,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引起的,而存档和取消存档保留了实例的正确易变属性!我遇到了一个问题,即存档三维易变数组(即易变数组的易变数组)将不归档为不可变数组的可变数组或不可变数组 解决这个问题的关键是将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;
}
它不识别的选择器是什么?编辑:好的,向下滚动查看。您定义了自定义的
CompareDate:
方法吗?还有,数组中的对象是什么类型的?我定义了它。我添加了代码,所以您可以查看它。我假设它必须是可变的才能排序,因为按定义排序会更改数组中对象的位置。(意思是添加和删除)。我错了吗?@Idan:您不能对不可变数组执行就地排序,但您可以向任何数组请求按特定选择器(或函数)排序的自身版本,使用kperryua提到的SortedArrayingSelector:
。好吧,我明白了,那么你如何解释无法识别的选择器异常?奇怪的是,它大部分时间都能工作。有什么想法吗?NSArray根本不响应-sortUsingSelector:因为这是一种变异方法,所以Objective-C抛出了异常。我不确定为什么会这样“大部分时间”。
// 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]]];
- (Class)classForClassName:(NSString *)codedName
{
Class theClass = [super classForClassName: codeName];
if ([codeName isEqualToString: NSStringFromClass(NSArray.class))
{
theClass = NSMutableArray.class;
}
//... more here like NSDictionary
return theClass;
}