2009-04-21 16 views
0

私は長い間この同じ問題を見つめていて、本当に助けや提案を感謝しています。私は何かシンプルだと確信していますが、私はそれを見つけることができません。私のアプリのデリゲートで、私は次のコードで(NSCopyingをサポートして私が作成したオブジェクトを、)アクセサリーオブジェクトの束をアップロードしています:iPhone SDKのmem管理の問題 - EXC_BAD_ACCESS

NSString  *path = [[NSBundle mainBundle] pathForResource:@"Accessories" ofType:@"plist"]; 
NSDictionary *accDict = [[NSDictionary alloc] initWithContentsOfFile:path]; 

self.colors = (NSArray *) [accDict objectForKey:@"Colors"]; 
self.exteriorAccessories = [self loadAccessoriesForMode:EXTERIOR_MODE withDictionary:accDict]; 
self.interiorAccessories = [self loadAccessoriesForMode:INTERIOR_MODE withDictionary:accDict]; 
[accDict release]; 

そして、これは、メソッドの呼び出しの定義は次のとおりです。

-(NSArray *)loadAccessoriesForMode:(NSString *)mode withDictionary:(NSDictionary *) dictionary 
{ 
    NSMutableArray *tempValues = [[NSMutableArray alloc] init]; 
    for (NSDictionary *value in [dictionary objectForKey:mode]) 
    { 
     Accessory *accessory = [[Accessory alloc] initWithDictionary:value]; 
     [tempValues addObject:accessory]; 
     [accessory release]; 
    } 

    NSArray *returnArray = [[NSArray alloc] initWithArray:tempValues copyItems:YES]; 
    [tempValues release]; 
    [returnArray autorelease]; 

    return returnArray; 
} 

私がaccDictのリリースを取得したとき、私はEXC_BAD_ACCESSの例外を受け取ります。ループ内のアクセサリーのリリースを取り除くと、すべてが問題ありませんが、私はAccessoryオブジェクトを漏らしています(私はそれを初期化して割り当てます。

これをデバッガでステップ実行すると、init、copy、およびdeallocメソッドがすべてアクセサリオブジェクトに期待通りに起動するのが見えます。アクセサリーオブジェクトのコードを投稿することもできますが、それが役に立ちそうだと思うのですが、問題はこのコードのどこかにあると思います。

答えて

3

私は原因を見つけたと思うが、他の人にもメリットがあるようにここに投稿する予定だ。私が投稿したコードとはまったく関係がありませんでした。むしろ問題はアクセサリオブジェクトの内部にありました。自分でゲッターを呼び出すのではなく、直接物事を設定していました。

ので、この:

value = [dict objectForKey:@"myKey"]; 

の代わりにこの:

self.value = [dict objectForKey:@"myKey"]; 

どういうわけか、これは私はNSDictionaryの自体に悪い副作用を持つように引き起こしていた(私はそれが変更可能ではなかったと思ったが、それはそう私は何とか物事を台無しにしていた)。私がこれを見つけた唯一の方法は、非常に役に立つアドバイスthat I found on Cocoa With Loveを使うことでした。

XCodeでPrint Descriptionオプションを使用したとき、NSDictionaryにAccessoryValueオブジェクトが含まれていたことがわかりました。カスタムオブジェクトの1つは単純なplistからロードされていたためでした。オブジェクトの詳細を表示する(デバッガでプロセスが一時停止している間)、オブジェクトの詳細に展開されている三角形のすぐ横にある小さな上/下の矢印をクリックして、XCodeで印刷説明を見つけることができます。辞書の場合、これはコンソール全体に内容をダンプします。

+0

それは、プロパティ「値」はそのアクセサメソッドで何が起こっているかに定義され方法を知っておくことが重要ですの。そこに保持され、リリースされていますか? –

+0

はい、値は(非原子、保持)を持つプロパティです。だから私の感心したのは、 "value ="を呼び出すことで、その呼び出しがretainを呼び出すようにポインタを設定するのに対し、 "self.value ="は適切なセッターメソッドを呼び出してretainを呼び出すことでした。 – Bdebeez

0

「私は客観的Cについて何も知らないけど」と、この接頭辞を付けてください:

あなたは「returnArray」にそれらをコピーした後に付属アイテムをリリース、または多分指定しないでする必要があるようですが、私には見えます"copyItems"。

0

コードでRun Clangを実行します。それは神様です。 Clangルール!それはあなたのコードの静的解析を行い、あなたが漏れているかもしれないことを教えます。素晴らしいもの。

0

私はExc_Bad_Accessの問題で1日対戦し、最終的に答えを見つけました。この問題は、NSDictionaryに格納されているオブジェクトの1つにアクセスしようとしたときに発生しました。最初はOKでしたが、オブジェクトの数が同じでもオブジェクトはゼロになりました。この奇妙な振る舞いは、オブジェクトを2度リリースすることによるものです。ここに例があります:

NSString * nstring = [[NSString alloc] init] autorelease [AnNSDictonaryInstance setObject:nstring forKey:0];

... [nstring release];

nstringが自動解放に設定されてから再度リリースされることに注意してください。 2回目に辞書オブジェクトを読み込もうとするとすぐに問題が表示されません。 Appleの開発チームがコンパイル中にこれを違反として報告することができるようになることを祈っています。

私はこの投稿が誰かを助けてくれることを願っています。

ウェイン・キャンベル