2011-10-18 13 views
0

私は目的のCコードでメモリリークに少し問題があります。誰も見て、彼らが何を考えるか教えてもらえますか?iOS NSMutableArrayメモリリーク

NSStringArray.h

@interface NSStringArray : NSObject { 

NSMutableArray *realArray; 

} 

@property (nonatomic, assign) NSMutableArray *realArray; 

-(id)init; 
-(void)dealloc; 
@end 

NSStringArray.m

#import "NSStringArray.h" 


@implementation NSStringArray 

@synthesize realArray; 

-(id)init { 

self = [super init]; 
if (self != nil) { 
    realArray = [[[NSMutableArray alloc] init] retain]; 
} 
return self; 
} 

-(void)dealloc { 
[realArray release]; 
realArray = nil; 
[super dealloc]; 
} 

Factory.m

+(NSStringArray *)getFields:(NSString *)line { 
//Divides the lines into input fields using "," as the separator. 
//Returns the separate fields from a given line. Strips out quotes & carriage returns. 

line = [line stringByReplacingOccurrencesOfString:@"\"" withString:@""]; 
line = [line stringByReplacingOccurrencesOfString:@"\r" withString:@""]; 

NSStringArray *fields = [[NSStringArray alloc] init]; 

for (NSString *field in [line componentsSeparatedByString:@","]) { 
    [fields.realArray addObject:field]; 
    [field release];  
} 

return [fields autorelease]; 
} 

リークツールがフィールドが割り当てられているときに漏れが発生することを言っており、フィールド配列にフィールド文字列を追加しています。

また、この関数は、私が解析しているファイルの各行と呼ばれています。

ヒントを教えてください。

ありがとうございます!

答えて

3

このコードでは、メモリ管理ルールを破棄します。

for (NSString *field in [line componentsSeparatedByString:@","]) { 
    [fields.realArray addObject:field]; 
    [field release];  
} 

fieldが指すオブジェクトを所有していないため、リリースしないでください。

あなたはすでに解放されたフィールドを持っていますので、それを解放する最後のオブジェクト(あなたのケースでは自動解放プール)がすでにdeallocされたオブジェクトを解放しています。

+0

それは問題でした!どうもありがとうございます! –

4

この行は、二重の保持ん:

realArray = [[[NSMutableArray alloc] init] retain]; 

それが十分

realArray = [[NSMutableArray alloc] init]; 
+0

これも私が思ったことですが、私がEXIT_BAD_ACCESSを使用してアプリケーションをクラッシュさせてしまいます。 –

+1

@Erik Rodriguez:あなたはどこかに問題があります。 – Chuck

+1

これは正しいです(+1)が、あなたが保持を外したときにクラッシュする理由についての私の答えを参照してください。 – JeremyP

1

ですthe docsから:

割り当てメッセージは メモリを割り当てる以外にも重要なことを行います

  • オブジェクトの保持カウントを1に設定します(「How Memory の管理」を参照)。

したがって、割り当て済みのものを保持する必要はありません。

+0

これも私が思ったことですが、私がEXIT_BAD_ACCESSを使用してアプリケーションをクラッシュさせてしまうと、自動解放プールが解放されると、クラッシュするように見えます。 –

+0

これは、あなたがしてはならないものをリリースしているからです。 @ JeremyPの答えを読んで、[Memory Management Rules](http://tinyurl.com/6ktdglb)を読んでください。 – Caleb

1

上記のFelzの回答に追加してください。あなたがまたに客観Cでの特性の利点を取ることができる「自己

1

を使用することをお勧めしますので、配列

self.realArray = [[NSMutableArray alloc] init]; 

を割り当てるあなたは、配列のプロパティを作成しているので使用self.realArray コードをより明確かつ効率的に作成してください。

NSStringArray。時間

@interface NSStringArray : NSObject { 
} 
@property (nonatomic, retain) NSMutableArray *realArray; 
@end 

NSStringArray.m

#import "NSStringArray.h" 

@implementation NSStringArray 

@synthesize realArray = _realArray; 

-(id)init { 

self = [super init]; 
if (self) { 
    self.realArray = [NSMutableArray array]; 
} 
return self; 
} 

-(void)dealloc { 
[_realArray release]; 
[super dealloc]; 
} 

さて、あなたは自動解放可変配列を返す [NSMutableArray array]を使用することができますrealArrayプロパティの修飾retainと。

保持プロパティは、保持/解放の内容を単独で管理します。

realArray = nil;行を使用する必要はありません。既に の資産を解約しました。

これは役に立ちます。

+0

優れた優れたアドバイス!私はまだ客観的に新しいです - Cとどのようなベストプラクティスも非常に歓迎されています!ありがとう! –