归档可变数组 - doesNotRecognizeSelector 异常
我遇到“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;
}
I'm having an "doesNotRecognizeSelector" exception and I suspect that maybe my unarchiver return immutable array intstead of mutable.
Am I right ? how should I do the archiving and archiving properly ? (place of exception is show down)
Thanks!!!
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`
}
- Edit
Adding the compare method:
- (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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
NSKeyedUnarchiver
确实返回一个不可变的NSArray
。如果您确实想要获取NSMutableArray
,则需要对decodeObjectForKey:
的返回值调用-mutableCopy
。这段代码片段让我想知道你是否真的需要一个可变数组。看起来您只是对从
-read
获得的数组进行排序。为什么不直接在不可变的 NSArray 上调用sortedArrayUsingSelector:
呢?NSKeyedUnarchiver
does indeed return an immutableNSArray
. If you really want to get anNSMutableArray
, you'd need to call-mutableCopy
on the return value fromdecodeObjectForKey:
.This code snippet makes me wonder if you really even need a mutable array though. It looks like you're just sorting the array you get from
-read
. Why not just callsortedArrayUsingSelector:
on the immutable NSArray instead?您已经将一个不可变数组传递给归档器,那么为什么您期望解归档器返回一个可变数组呢?
如果您希望副本是可变的,那么您必须使用
as
将创建一个不可变的副本(至少就您应该关心的而言)。实际上,框架通常会为不可变的实例使用可变的内部表示,但这是一个实现细节,你不应该指望它,因为这些表示在过去已经改变,并且 Cocoa 文档明确告诉你,不要检查内部表示)。
编辑:
刚刚在 iOS 5.0 模拟器上使用 NSKeyedArchiver 进行了测试:
所以您的问题实际上完全是由使用 copy 而不是 mutableCopy 引起的,而归档和取消归档保留了实例的正确可变性属性!
You already pass an immutable array to the archiver, so why would you expect the unarchiver to return a mutable one then?
If you want a copy to be mutable, then you have to use
as
will create an immutable copy (at least as far, as you should be concerned. In reality the framework will often use a mutable internal representation for immutable instances, but this is an implementation detail and you should not count on it, as these representations have changed in the past and the Cocoa docs explicitly tell you, to not check for the internal representation).
EDIT:
just tested with NSKeyedArchiver myself on iOS 5.0 simulator:
So your problem is really exclusively caused by using copy instead of mutableCopy, while archiving and unarchiving keeps the correct mutability-attributes of the instances!
我遇到了一个问题,即归档 3 维可变数组(即可变数组的可变数组的可变数组)将作为不可变数组的不可变数组的可变数组取消归档。
解决这个问题的关键是子类 NSKeyedUnarchiver 并覆盖
I had an issue where archiving a 3-dimensional mutable array (ie, a mutable array of mutable arrays of mutable arrays) would unarchive as a mutable array of immutable arrays of immutable arrays.
The key to fixing this was to subclass NSKeyedUnarchiver and overwrite