0

を使用してオブジェクトの可変配列を永続化するのに問題がありますNSUserDefaults。私は何日も別のコードを試してきましたが、うまくいきません。StackOverflow のすべての投稿を含め、この件に関して見つけられるものはすべて読みました。私は自分が近いことを知っていますが、誰かが私が間違っていることを指摘してくれることを本当に感謝しています. arr次のコードではカウントが 0 になることがわかっていますが、ここで障害にぶつかりました。私はその点を過ぎていません。私の投稿を読んでから 2 分以内に、誰かが笑って私のばかげた間違いを指摘してくれるに違いありません。

ログを含む関連コードは次のとおりです。

Contacts.h:

 @interface Contacts : NSObject  // <NSCoding>
{
    NSMutableArray *arr;    // 8/21/13
}

Contacts.m

- (void)encodeWithCoder:(NSCoder *)aCoder
{
      NSLog(@"In encodeWithCoder");
      NSLog(@"In encodeWithCoder. arr's count is: %i", [arr count]);
    {
       for (int i = 0; i <[arr count]; i++)
       {
            NSLog(@"In encodeWithCoder %@", [arr objectAtIndex:i]);
            NSLog(@"class %@", [arr class]);
       }
     [aCoder encodeObject:arr forKey:@"allContacts"];
    }
}

- (id) initWithCoder:(NSCoder *)aDecoder
{
    NSLog(@"In initWithCoder");
    arr = [aDecoder decodeObjectForKey:@"allContacts"];
    return self;
}

// The following two methods might not even be needed. I copied them from some examples.

- (NSData *)dataOftype:(NSString *)typeName error:(NSError **)outError
{
    return nil;
}

- (BOOL)readFromData:(NSData *)data oftype:(NSString *)typeName error: (NSError **)outError
{
    arr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    NSLog(@"allContacts is ->%@", [arr mutableCopy]);
    return YES;
}

ContactStore.h

@interface ContactsStore : NSObject <NSCoding>
{
    NSMutableArray *arr;            // 8/21/13
    NSMutableArray *allContacts;    
}

ContactStore.m

    - (void)fetchContactsIfNecessary
{
    NSLog(@"in ContactsStore.m - fetchContactsIfNecessary #1");
    if (!allContacts)
    {
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSData *data = [defaults objectForKey:@"allContacts"];
        allContacts = [[NSMutableArray alloc]initWithArray:[NSKeyedUnarchiver    unarchiveObjectWithData:data]];
        for (int i = 0; i <[allContacts count]; i++)
        {
            NSLog(@"In FetchContactsIfNecessary- Gettingfrom NSUserDefaults %@", [allContacts objectAtIndex:i]);
            NSLog(@"In FetchContactsIfNecessary- Gettingfrom NSUserDefaults - class %@", [allContacts class]);
        }
    }

    // If we didn't find one in NSUserDefaults, then create a new one.
    if (!allContacts)
    {
        allContacts = [[NSMutableArray alloc] init];
        NSLog(@"In FetchContactsIfNecessary-We just allocated allContacts");
    }
    NSLog(@"in ContactsStore.m - Leaving fetchContactsIfNecessary2");
}


- (BOOL)saveChanges
{
    for (int i = 0; i <[allContacts count]; i++)
    {
        NSLog(@"In saveChanges %@", [allContacts objectAtIndex:i]);
        NSLog(@"In saveChanges class %@", [allContacts class]);
    }
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    arr = allContacts;   // 8/21/13
        NSLog(@"In saveChanges. arr's count is: %i", [arr count]);
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
    [defaults setObject:data forKey:@"allContacts"];
    [[NSUserDefaults standardUserDefaults] synchronize];
       NSLog(@"We just synchronized allContacts - I think");
    return 1;
}

ログ

2013-08-22 14:13:50.764 ImOK[16979:907] In saveChanges Scott Stringer, (212) 888-1234
2013-08-22 14:13:50.772 ImOK[16979:907] In saveChanges class __NSArrayM
2013-08-22 14:13:50.775 ImOK[16979:907] In saveChanges Sheldon Silver, (212) 987-4321
2013-08-22 14:13:50.781 ImOK[16979:907] In saveChanges class __NSArrayM
2013-08-22 14:13:50.793 ImOK[16979:907] In saveChanges. arr's count is: 2
2013-08-22 14:13:50.795 ImOK[16979:907] In encodeWithCoder
2013-08-22 14:13:50.796 ImOK[16979:907] In encodeWithCoder. arr's count is: 0
2013-08-22 14:13:50.798 ImOK[16979:907] In encodeWithCoder
2013-08-22 14:13:50.799 ImOK[16979:907] In encodeWithCoder. arr's count is: 0
2013-08-22 14:13:50.805 ImOK[16979:907] We just synchronized allContacts - I think

アプリがバックグラウンドから戻った後、名前と電話番号は正しく表示されますが、アプリを再起動すると null が 4 つしか表示されません。arrのカウントがメソッドでゼロであるため、私はそれを期待していましたencodeWithCoderが、この問題を解決する方法がわかりません。

4

1 に答える 1

0

オブジェクトをエンコードおよびデコードするだけです。まだ保存していません。それを保存するには、次のような関数が必要です。

- (BOOL)storeBrandOnDevice
{
    NSString *path = [self itemArchivePath];
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:self forKey:@"Contacts"];
    [archiver finishEncoding];
    BOOL dataSaveSuccess = [data writeToFile:path atomically:YES];

    return dataSaveSuccess;
}

次のようなストアからそれらを取得するには: - (void) getBrandFromStorage {

NSString *path = [self itemArchivePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:path];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    Contacts* storedContacts = [unarchiver decodeObjectForKey:@"Contacts"];
    [unarchiver finishDecoding];
}

}

そして、ここにあなたの欠けている機能があります:

- (NSString*)itemArchivePath
{

    @try {

        NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString* documentDirectory = [documentDirectories objectAtIndex:0];

        return [documentDirectory stringByAppendingPathComponent:@"items.archive"];
    }
    @catch (NSException *exception) {
        return nil;
    }
}

完璧ではないかもしれませんが、それが一般的なコンセプトです。

NSCoding の詳細については、Ray Wenderlich のチュートリアルに従ってください。

于 2013-08-22T19:15:53.280 に答える