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;
}

当我想使用这个类时遇到的问题 - 显然是由于我对内存管理的误解。

在我的视图控制器中,我声明如下:

(在@界面中):

MapFileGroup *fullGroupOfMaps;

使用@property@property (nonatomic, retain) MapFileGroup *fullGroupOfMaps;

然后在 .m 文件中,我有一个名为的函数loadMapData,它执行以下操作:

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

// 对于所有以 .png 结尾的字符串(不区分大小写) NSPredicate *caseInsensitivePNGFiles = [NSPredicate predicateWithFormat:@"SELF endswith[c] '.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
}

Some methods return autoreleased objects as a convenience to you, so that you don't have to manage the memory yourself (it will be cleaned up automatically). In the case of instance variables, you almost never want them to be cleaned up by automatically.

You can also prevent an autoreleased object from being automatically released by retaining it again.

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

The Cocoa Memory Management Programming Guide has a few simple rules to follow about when you should explicitly release, and when you should explicitly retain. Keep the link bookmarked until the rules have become second nature and you'll have no troubles with Cocoa Memory Management. It is much simpler than it originally seems (or at least, that was the case for me).

于 2010-05-07T09:24:11.790 回答