2010-05-07 42 views
0

我遇到了一些Objective-C的问题,并希望得到一些指示。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; 
} 

我得到的问题是当我想使用这个类 - 显然是由于我对记忆管理的误解。

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

(在@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 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类的实例变量?创建对象的正确方法是添加到类中,以便在我完成之前不会释放它们?

非常感谢

回答

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内存管理问题。它比最初看起来简单得多(或者至少对我而言是这样)。

+0

感谢您的帮助 - 我一直在阅读内存管理规则,但仍然每时每刻都被绊倒(有点太习惯于新的和免费的我认为)。我仍然有一个数组中的范围内的问题,但是,'mapfile = [[MapFile alloc] initWithName:nameOfMap]; [mapfile retain]; //添加到数组 [fullGroupOfMaps addMapFile:mapfile];'添加它们,但它们超出范围。我认为addObject会执行保留? – davbryn 2010-05-07 09:39:35

+0

我的不好,在C++和Obj-C之间不会让生活变得轻松。我一直在为我的类创建@properties,但没有使用self.variable_name来获取/设置,因此没有发生保留:( – davbryn 2010-05-07 10:20:48