代码之家  ›  专栏  ›  技术社区  ›  davbryn

目标C超出范围问题

  •  0
  • davbryn  · 技术社区  · 15 年前

    我对一些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*caseInsensitivePNG文件= [n预测谓词格式:@“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 稍后。它调用 全组映射 ,但如果我在调试时从该行进入类,则 全组映射 的对象现在超出范围,我遇到了崩溃。

    很抱歉问了这么长的问题和这么多代码,但我想我的主要问题是:

    我应该如何处理将nsmutablearray作为实例变量的类?创建要添加到类中的对象以使它们在我处理完之前不会被释放的正确方法是什么?

    非常感谢

    1 回复  |  直到 15 年前
        1
  •  2
  •   dreamlax    15 年前

    当你打电话 [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 有几个简单的规则可以遵循,当你应该显式释放,当你应该显式保留。保持链接书签,直到规则成为第二天性,你就不会有可可内存管理的麻烦。它比最初看起来简单得多(或者至少对我来说是这样)。

    推荐文章