2009-09-04 2 views
2

このを通じてデバッガでステップ実行すると、dfStringが無効である[DFリリース]この文字列をコピーして自動解放する必要がありますか?

- (NSString*)dateFormatStringWithLocale:(NSLocale*)locale { 
    NSDateFormatter* df = [[NSDateFormatter alloc] init]; 
    [df setDateStyle:NSDateFormatterShortStyle]; 
    [df setTimeStyle:NSDateFormatterShortStyle]; 
    [df setLocale:locale]; 
    NSString *dfString = [df dateFormat]; // dfString now contains nice date format 
    [df release]; // seems to also kill dfString ??? 
    return dfString; // dfString is invalid here 
} 

後のは、それについて考えてみましょう:dfStringは、他のと同じように、オブジェクトです。私は[df dateFormat]でdfから文字列を要求します。私はその文字列を所有していないので、私はそれを解放する必要はありません。しかし、私はdfを所有しているので、私はそれをリリースします。今、[df dateFormat]から得た文字列がdfのいくつかのivarであり、dfの-deallocで-release'dを取得すると仮定してください。そして、その呪われた弦は消えてしまった。しかし、私がdfStringが所有する文字列へのポインタにすぎないdfStringを呼び出すと、damn dfは解放されません。だから私は何をしますか?文字列をコピーして自動解放しますか?大会はobj-にインスタンスメソッドであるとして、あなたが完全に自動解放オブジェクトを返しているその方法を

NSDateFormatter *df = [[[NSDateFormatter alloc] init] autorelease]; 

を放し

[df release]; // Remove this line 

を削除:自動解放するNSDateformatterを設定し

+0

それは質問のための素晴らしいタイトルではありません...私はそれを変更する担当者を持っていない私は恐れている! : – h4xxr

+0

それを変更しました。それは今より良いかもしれませんか? –

答えて

2

私はあなたが言うように、行う自動解放文字列を作り、いずれか、次のようにしたい:

NSString *dfString = [NSString stringWithString: [df dateFormat]]; 

またはそのような:

NSString *dfString = [[[df dateFormat] copy] autorelease]; 

私は最初のものを好むが、ありますなら、私を修正してください何か間違っている。

+0

これはうまくいくはずですが、元の文字列の所有権を簡単に取ることができ、dfはそれをゴミ箱に入れません。 – mahboudz

1

c

+0

私はそれが正しいとは思わない。彼はdfを返さないので、オートリリースされる必要はない。 –

+0

必要なものがインスタンス変数(プロパティ)のいずれかである場合、dfをすべて保持する必要はないと思います。 – mahboudz

0

私はあなたの理解が正しいと思っています。(少なくとも検査によって)あなたのコードも正しく見えます。

私の推測では、デバッガは、おそらくコンパイラの最適化レベルなどに関連する真実を完全には伝えていないと思います。

+0

実際に私はコードにバグがありました。 dfのrelaseは、文字列をニルヴァーナに移動させました。 –

0

はこれを試してみてください:

NSString *dfString = [[df dateFormat] retain]; 

dfStringがdfStringのインスタンス変数である可能性がありますのでDFがリリースされたとき、それはdealloc'edなっています。 dfStringをそのまま使用してみてください。 deallocでは、retainCountは1つ下がってしまいますが、所有権があるので完全に解放されることはありません。それが役立つかどうかを見てください。

+0

完了したらこれをリリースしなければならない、またはこれをautoreleaseとしてマークすることができますが、runloopが終了する前に完了しなければなりません。 – mahboudz

1

所有権の問題です。フォーマッタはあなたが見ている文字列を所有しています。したがって、フォーマッタが消えると文字列は消滅します。あなたは何とかコピーや保持を使って、その文字列の所有権を主張する必要があります。

これは実際にアクセサメソッドがどのように実装されているかによって異なります。以下のどちらの実装は完全に有効です。

実際
- (NSString*) dateFormat 
{ 
    return dateFormat; 
} 


- (NSString*) dateFormat 
{ 
    return [[dateFormat copy] autorelease]; 
} 

のみ適切な最初の1あなたはDATEFORMATは不変NSStringであることを確認することができます。私。あなたが手渡された文字列のコピーを作成した場合。それ以外の場合は、呼び出し側があなたが所有する文字列を変更するように誘惑されるかもしれません。

関連する問題