Cocoa メモリ管理ガイドを読む必要があります。
コードで実行していることのいくつかは、ココア メモリ管理の基本的な概念を把握していないことを示しています。
例えば:
[Foo alloc];
「foo」を初期化していません。alloc
結合しinit
て一緒に呼び出すことは一般的な方法です。たとえば、[[Foo alloc] init];
これにより、オブジェクトのメンバーと状態が作成後に期待どおりになることが保証されます。
name2 = [foo bar]; // returns a (NSString *)
このbar
メソッドはautoreleased
文字列を返す可能性があります。に割り当てた後は保持していないname2
ため、メソッドが戻った後、しばらくして割り当てが解除されます。これが、コードがクラッシュする理由です。割り当てが解除されたオブジェクトにアクセスしようとしています。指していたオブジェクトname2
は解放され、割り当てが解除されましたが、ポインターは nil に設定されていませんでした。つまり、ポインターが指しているメモリには何でも含めることができます。未定義です。
機能する理由name1
は、Cocoa でリテラル @"" 文字列を使用する際の特別な考慮事項のためです。文字列がこのように使用されると、「内部化」されます。同じテキストを含む 2 つのリテラル文字列を作成すると、両方の文字列がメモリ内の 1 つのオブジェクトを指すようにシステムが最適化します。
つまり、次のようなコードがあるとします。
NSString *myString1 = @"hello";
NSString *myString2 = @"hello";
NSLog(@"string1: %p, string2: %p", myString1, myString2);
次のようなメッセージになりますstring1: 0x123456, string2: 0x123456
。ここで注目すべき重要な点は、メモリ アドレスが同じであることです。コード内では異なるインスタンスですが、文字列は同じオブジェクトを指しています。