2

これらの2つの方法は(メモリ割り当てに関して)同等だと思いましたが、便利な方法(以下にコメント)を使用して切り替えたときに、デバッガーに「範囲外」と「NSCFString」が表示されていました。より明示的な方法で、私のコードはクラッシュしなくなりました!sqlite3クエリからコンテナに保存されている文字列を取得していることに注意してください。

p = (char*) sqlite3_column_text (queryStmt, 1);
// GUID = (NSString*) [NSString stringWithUTF8String: (p!=NULL) ? p : ""];
GUID = [[NSString alloc] initWithCString:(p!=NULL) ? p : "" encoding:NSUTF8StringEncoding];

また、デバッガーで値を確認し、NSLogで出力した場合、それらは正しいように見えましたが、新しいメモリが割り当てられ、値がコピーされたとは思わないことにも注意してください。代わりに、メモリポインタが保存されました-スコープ外になりました-後で参照されます-クラッシュします!

4

1 に答える 1

0

メソッドが戻った後もオブジェクトへの参照を保持する必要がある場合は、オブジェクトの所有権を取得する必要があります。したがって、変数GUIDがインスタンス変数またはある種のグローバルである場合は、オブジェクトの所有権を取得する必要があります。alloc / initメソッドを使用する場合は、を使用してから返されたオブジェクトの所有権がありますalloc。この方法も同じように簡単に使用できstringWithUTF8String:ますが、メッセージを送信して明示的に所有権を取得する必要がありretainます。したがって、GUIDある種の非メソッドスコープ変数を想定します。

GUID = [[NSString stringWithUTF8String:"Some UTF-8 string"] copy];

copyまたはretainここで所有権を取得するために使用できますがcopy、文字列を処理する場合により一般的です)。

また、次のようなことをすると、コードが少し読みやすくなる可能性があります。

GUID = p ? [[NSString stringWithUTF8String:p] copy] : @"";
于 2010-04-18T18:13:03.793 に答える