Objective-C Вне области видимости проблема - PullRequest
0 голосов
/ 07 мая 2010

У меня есть несколько проблем с Objective-C, и я был бы признателен за некоторые указатели.

Итак, у меня есть класс MapFileGroup, который имеет следующий простой интерфейс (есть другие переменные-члены, но они не важны):

@interface MapFileGroup : NSObject {
 NSMutableArray *mapArray;

}

@property (nonatomic, retain) NSMutableArray *mapArray;

mapArray - это @synthesize 'd в файле .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 ПредикатWithFormat: @ "SELF заканчивается с [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 в качестве переменной экземпляра? Как правильно создавать объекты, добавляемые в класс, чтобы они не освобождались до того, как я с ними закончу?

Большое спасибо

1 Ответ

2 голосов
/ 07 мая 2010

Когда вы звоните [NSMutableArray arrayWithCapacity:], это на самом деле создает & ldquo; autoreleased & rdquo; массив. Это означает, что он будет выпущен автоматически через некоторое время в будущем. Обычно он освобождается в конце текущего цикла выполнения.

То, что вы хотите сделать, - это создать массив, который не выпускается автоматически, потому что вы хотите явно освободить его, когда закончите с ним. Для этого используйте:

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

Не забывайте, вам нужно отпустить, когда вы закончите с этим. Обычно, если переменная экземпляра инициализируется в инициализаторе класса, она должна быть освобождена в методе dealloc класса, например:

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

Некоторые методы возвращают автоматически выпущенные объекты для вашего удобства, так что вам не нужно самим управлять памятью (она будет очищена автоматически). В случае переменных экземпляра вы почти никогда не хотите, чтобы они автоматически очищались.

Вы также можете предотвратить автоматическое освобождение автоматически освобожденного объекта, сохранив его снова.

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

Руководство по программированию управления памятью какао имеет несколько простых правил, которым нужно следовать, когда вы должны явно освобождать, и когда вы должны явно сохранять. Сохраняйте ссылку в закладке, пока правила не станут второй натурой, и у вас не возникнет проблем с управлением памятью какао. Это намного проще, чем кажется на первый взгляд (или, по крайней мере, так было у меня).

...