我在使用一些Objective-C时遇到了一些问题,并且会很感激。
所以我有一个类MapFileGroup
,它有以下简单的接口(还有其他成员变量,但它们并不重要):
@interface MapFileGroup : NSObject {
NSMutableArray *mapArray;
}
@property (nonatomic, retain) NSMutableArray *mapArray;
mapArray
在.m文件中为@synthesize
。
它有一个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;
}
当我想使用这个类时,我得到的问题显而易见 - 显然是由于我对内存管理的误解。
在我的视图控制器中,我声明如下:
(在@interface中):
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 endwith [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作为实例变量的类?创建要添加到类中的对象的正确方法是什么,以便在我完成它们之前不会释放它们?
非常感谢
答案 0 :(得分: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 Memory Management Programming Guide有一些简单的规则可供您明确释放,以及何时应明确保留。保持链接书签,直到规则成为第二天性,你可以没有Cocoa内存管理的麻烦。它比最初看起来要简单得多(或者至少,对我来说就是这种情况)。