Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 存档可变数组-不可识别选择器异常_Iphone_Objective C_Cocoa Touch_Immutability_Archiving - Fatal编程技术网

Iphone 存档可变数组-不可识别选择器异常

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

我有一个“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`
}

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