3

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

3 に答える 3

6

NSKeyedUnarchiver確かに不変を返しNSArrayます。本当に を取得したい場合は、 からの戻り値NSMutableArrayを呼び出す必要があります。-mutableCopydecodeObjectForKey:

このコード スニペットを見ると、可変配列が本当に必要なのかどうか疑問に思います。から取得した配列をソートしているようです-readsortedArrayUsingSelector:代わりに、不変の 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 の代わりに copy を使用することによってのみ発生します!

于 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 に答える