0

私はいくつかの Objective-C でいくつかの問題を抱えており、いくつかの指針をいただければ幸いです。

だから私は次の単純なインターフェースを持つクラスMapFileGroupを持っています(他のメンバー変数がありますが、それらは重要ではありません):

@interface MapFileGroup : NSObject {
 NSMutableArray *mapArray;

}

@property (nonatomic, retain) NSMutableArray *mapArray;

mapArray@synthesize.m ファイルに含まれています。

init メソッドがあります。

-(MapFileGroup*) init
  {
    self = [super init];
    if (self)
    {
       mapArray = [NSMutableArray arrayWithCapacity: 10];
    }

    return self;
  }

また、配列にカスタム オブジェクトを追加するメソッドもあります。

-(BOOL) addMapFile:(MapFile*) mapfile
{
if (mapfile == nil) return NO;

mapArray addObject:mapfile];
return YES;
}

このクラスを使用したいときに問題が発生します-明らかに、私の側のメモリ管理の誤解が原因です。

私のView Controllerでは、次のように宣言します。

(@interface で):

MapFileGroup *fullGroupOfMaps;

@プロパティ付き@property (nonatomic, retain) MapFileGroup *fullGroupOfMaps;

次に、.m ファイルにloadMapDataは、次のことを行う関数が呼び出されます。

MapFileGroup *mapContainer = [[MapFileGroup alloc] init];
// create a predicate that we can use to filter an array

// .png で終わるすべての文字列 (大文字と小文字を区別しない)

mapNames = [unfilteredArray filteredArrayUsingPredicate:caseInsensitivePNGFiles];
[mapNames retain];

NSEnumerator * enumerator = [mapNames objectEnumerator];
NSString * currentFileName;
NSString *nameOfMap;
MapFile *mapfile;


while(currentFileName = [enumerator nextObject]) {
  nameOfMap = [currentFileName substringToIndex:[currentFileName length]-4]; //strip the extension

mapfile = [[MapFile alloc] initWithName:nameOfMap];
[mapfile retain];
// add to array
[fullGroupOfMaps addMapFile:mapfile];

}

これは問題なく動作しているようです (メモリ管理が適切に機能していないことはわかりますが、まだ Objective-C を学習中です)。ただし、後者(IBAction)と相互作用する がありfullGroupOfMapsます。内のメソッドを呼び出しますが、fullGroupOfMapsデバッグ中にその行からクラスにステップ インすると、すべてfullGroupOfMapsの のオブジェクトが範囲外になり、クラッシュします。

長い質問と大量のコードをお詫びしますが、私の主な質問は次のとおりです。

インスタンス変数として NSMutableArray を持つクラスをどのように処理すればよいですか? クラスに追加するオブジェクトを作成して、処理が完了する前にオブジェクトが解放されないようにする適切な方法は何ですか?

どうもありがとう

4

1 に答える 1

2

を呼び出すと[NSMutableArray arrayWithCapacity:]、実際には「自動解放」配列が作成されます。これは、将来のある時点で自動的にリリースされることを意味します。通常、現在の実行ループの最後に解放されます。

実行したいのは、自動解放されない配列を作成することです。これは、終了時に明示的に解放するためです。これを行うには、次を使用します。

mapArray = [[NSMutableArray alloc] initWithCapacity: 10];

忘れないでください、あなたがそれを終えたらそれを解放する必要があります。通常、インスタンス変数がクラスのイニシャライザーで初期化される場合、次のdeallocようにクラスのメソッドで解放する必要があります。

- (void) dealloc
{
    [mapArray release];
    [super dealloc]; // so that NSObject can clean up itself
}

一部のメソッドは、便利なように自動解放されたオブジェクトを返すため、メモリを自分で管理する必要はありません(メモリは自動的にクリーンアップされます)。インスタンス変数の場合、それらが自動的にクリーンアップされることはほとんどありません。

自動解放されたオブジェクトを再度保持することで、オブジェクトが自動的に解放されないようにすることもできます。

mapArray = [[NSMutableArray arrayWithCapacity:10] retain];

Cocoaメモリ管理プログラミングガイドには、明示的に解放する必要がある場合と、明示的に保持する必要がある場合について従うべきいくつかの簡単なルールがあります。ルールが第二の性質になり、Cocoaメモリ管理に問題がなくなるまで、リンクをブックマークしておいてください。それは当初の見た目よりもはるかに単純です(または少なくとも、私にとってはそうでした)。

于 2010-05-07T09:24:11.790 に答える