0

自分で作成したクラスEntryを使用して、特定のデータを配列に格納するアプリの作成に取り組んでいます。ただし、エントリ オブジェクトに格納されている値の 1 つにアクセスしようとすると、このエラーが発生し続けます。ユーザーにこれらのオブジェクトの 1 つを作成するように求めるたびに、それが「rawArray」に追加され、[NSUserDefaults standardUserDefaults] に格納されます。次のコード行で、プログラムがクラッシュします。

Entry *currEntry = [[[NSUserDefaults standardUserDefaults] arrayForKey:@"rawArray"] objectAtIndex:section];
NSLog(@"date: %@", [currEntry getDate]);

現在の UITableView セクションに対応する配列要素を取得しようとしているだけで、そこに格納されている「日付」変数を NSLog にします。Entry クラスの getDate メソッドを次に示します。

-(NSString *)getDate{
   return date;
}

日付オブジェクト自体は、クラスの init で設定される Entry クラスの別の NSString です。誰かがこの問題を解決するのを手伝ってくれるなら、私は信じられないほど感謝しています.

完全なクラッシュ ログは次のとおりです。

2012-04-24 16:31:32.545 Know[7278:f803] -[__NSCFString getDate]: unrecognized selector sent to instance 0x68598f0
2012-04-24 16:31:32.546 Know[7278:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString getDate]: unrecognized selector sent to instance 0x68598f0'
*** First throw call stack:
(0x13cb052 0x155cd0a 0x13ccced 0x1331f00 0x1331ce2 0xa930 0xb85c9 0xb8480 0x1fc849 0x1ff722 0xaf7c7 0xaf2c1 0xb228c 0xb6783 0x61301 0x13cce72 0x1d7592d 0x1d7f827 0x1d05fa7 0x1d07ea6 0x1d9330c 0x33530 0x139f9ce 0x1336670 0x13024f6 0x1301db4 0x1301ccb 0x12b4879 0x12b493e 0x22a9b 0x1d98 0x1cf5)
terminate called throwing an exception

NSKeyedArchiver/Unarchiver の使用に切り替えた後も、同じ問題に遭遇しました。これが私の新しい取得および保存メソッドです。

-(void)saveToUserDefaults:(NSMutableArray *)array{
    NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:array];
    [[NSUserDefaults standardUserDefaults] setObject:myEncodedObject forKey:@"rawArray"];
}

-(NSMutableArray *)loadFromUserDefaults{
    NSData *myDecodedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"rawArray"];
    NSMutableArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: myDecodedObject];
    return decodedArray;
}

プログラムをクラッシュさせるコードの新しい行は次のとおりです。

Entry *currEntry = [[self loadFromUserDefaults] objectAtIndex:section];
NSLog(@"date: %@", [currEntry getDate]);

そして、更新されたクラッシュ ログは次のとおりです。

2012-04-24 17:43:36.853 Know[10314:f803] -[__NSCFString getDate]: unrecognized selector sent to instance 0x6acc260
2012-04-24 17:43:36.904 Know[10314:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString getDate]: unrecognized selector sent to instance 0x6acc260'
*** First throw call stack:
(0x13ce052 0x155fd0a 0x13cfced 0x1334f00 0x1334ce2 0xb710 0xbb5c9 0xbb480 0x1ff849 0x202722 0xb27c7 0xb22c1 0xb528c 0xb9783 0x64301 0x13cfe72 0x1d7892d 0x1d82827 0x1d08fa7 0x1d0aea6 0x1d9630c 0x36530 0x13a29ce 0x1339670 0x13054f6 0x1304db4 0x1304ccb 0x12b7879 0x12b793e 0x25a9b 0x2a18 0x2975)
terminate called throwing an exception
4

5 に答える 5

2

問題は、NSUserDefaults を介してカスタム オブジェクトの配列を格納していることだと思います。たぶん、これに関するこの記事を確認する必要があります: How to Save array of custom class in NSUserDefaultsまたは this question

編集


encodeWithCoderメソッドとを追加しましたかinitWithCoder。おそらく問題はその実装にあります。

于 2012-04-24T20:48:23.870 に答える
1

これらの行からアプリがクラッシュする正確な原因は何ですか? 次の 3 つのケースが考えられます。

  1. standardUserDefaults から @"rawArray" によってインデックス付けされたアイテムにアクセスします。
  2. その配列からセクション インデックスにアクセスします。
  3. エントリー日にアクセスします。

問題は Entry クラスと NSUserDefaults に関連していると思います。オブジェクトを userDefaults に格納するには、NSCoding プロトコルに準拠する必要があります (NSArray と NSDictionary は既に準拠しており、それぞれのメソッドで基本型を使用することもできます)。

しかし、これが問題である場合、エントリも保存したときにアプリケーションがクラッシュしたと言わざるを得ません...そのため、何が起こっているのか正確にはわかりません。

どの方法でアプリがクラッシュするかをもう少し明確にしてください。幸運を!

于 2012-04-24T20:50:34.860 に答える
1

最初に使用するNSKeyedArchiver( に格納する前にNSUserDefaults)

このような:

保存:

NSData *dataForNSUserDefaults = [NSKeyedArchiver archivedDataWithRootObject:yourEntry];
[[NSUserDefaults standardUserDefaults] setObject:dataForNSUserDefaults forKey:@"yourKey"];

ロード:

NSData *archivedData = [[NSUserDefaults standardUserDefaults] objectForKey:@"yourKey"];
Entry *yourEntry = [NSKeyedUnarchiver unarchiveObjectWithData:arrayAsData];
于 2012-04-24T20:51:23.933 に答える
1

エラー メッセージは、エントリと思われるものが実際には文字列であることを示しています。私の最初の推測は、タイプの文字列記述に変換されているカスタム オブジェクト タイプを保存しようとしているということです。オブジェクトをログに記録して確認してください。

NSLog(@"Entry: %@", currEntry);

データ型に関する NSUserDefaults ドキュメントを見て、サポートされているものを確認してください。

于 2012-04-24T20:52:03.980 に答える
1

NSUserDefaultsカスタム クラスのインスタンスを格納できません。文字列、ブール値、辞書などの単純なものしか保存できません。

それがあなたが得ている理由です[__NSCFString getDate]: unrecognized selector sent to instance__NSCFStringNSString の Apple のプライベート クラスの 1 つです。基本的に、 への呼び出しが NSString をNSUserDefaults返し、 NSString には と呼ばれるメソッドがないと言っていますgetDate

データをシリアル化および逆シリアル化する必要があるため、オブジェクトを に格納するにはNSUserDefaults、まずオブジェクトをすべての値の辞書表現に変換する必要があります。次に、データをオブジェクトに戻す場合は、逆の操作を行います。通常、Key-Value コーディングが役立ちます。

ちなみにgetDateObjective-Cのメソッドネーミングには対応していません。という名前のクラスに合成されたプロパティがある場合は、そのプロパティの名前を指定してから、 を使用して合成するdate必要があります。@synthesize は getter メソッドと setter (アクセサとミューテータ) メソッドを作成してくれるので、orを呼び出すだけで、何をすべきかがわかります。ARC またはキーと値のコーディングを使用している場合、これは特に重要です。場合によっては、ランタイムがガイドラインに従っていると想定するからです。date@synthesize date = _date;setData:data

最後に、NSUserDefaults は本来の目的 (デフォルト) にのみ使用することを強くお勧めします。これには、設定やその他の非機密情報が含まれます。多くの変更や要求を行い始めると、パフォーマンスは良くありません。Documents ディレクトリ、SQLite、または Core Data に保存した plist を使用します。

于 2012-04-24T20:53:12.707 に答える