Ваши проблемы с памятью сводятся к проблеме владения. Когда у класса есть переменная экземпляра (например, monkeyRanch
), вы обычно создаете экземпляр в инициализаторе для этого класса, а затем освобождаете его в dealloc
, например:
@interface Monkey : NSObject {
NSMutableArray * monkeyRanch;
}
@end
@implementation Monkey
- (id)init {
if ((self = [super init]) == nil) { return nil; }
monkeyRanch = [[NSMutableArray alloc] initWithCapacity:0];
return self;
}
- (void)dealloc {
[monkeyRanch release];
}
@end
В этом случае классу Monkey
принадлежит член monkeyRanch
.
При вызове функций вы должны обязательно release
любые локальные объекты, которые вы init
, retain
или copy
. Похоже, у вас правильная часть, но я все же покажу быстрый пример:
- (void)someFunction {
NSNumber * myNumber = [[NSNumber alloc] init];
...
[myNumber release];
}
Следующее, что нужно понять, это то, что существует огромная разница между простой установкой переменной-члена и установкой значения свойства. То есть:
NSMutableArray * temp = [[NSMutableArray alloc] initWithCapacity:0];
monkeyRanch = temp;
[temp release]; // it's gone!
это не то же самое, что:
NSMutableArray * temp = [[NSMutableArray alloc] initWithCapacity:0];
self.monkeyRanch = temp; // now owned by self
[temp release];
В первом случае вы просто устанавливаете указатель (monkeyRanch) равным другому указателю (temp). Значение не сохраняется и не копируется.
Во втором случае вы фактически устанавливаете свойство. Это означает, что, предполагая, что свойство было сохранено, массив теперь принадлежит вашему объекту класса.
P.S:.
Возможно, вы идете по неправильному пути в плане дизайна. На мой взгляд, ранчо обезьян - это то, что содержит много обезьян. Если это так, то ваши Monkey
объекты действительно не должны иметь MonkeyRanch. Я бы вместо этого пошел с чем-то вроде этого:
Monkey.h
@class MonkeyRanch;
@interface Monkey : NSObject {
MonkeyRanch * ranch;
}
@property (nonatomic, assign) MonkeyRanch * ranch;
@end
Monkey.m
@implementation Monkey
@synthesize ranch;
@end
MonkeyRanch.h
#import "Monkey.h"
@interface MonkeyRanch : NSObject {
NSMutableArray * monkeys;
}
@property (nonatomic, retain) NSMutableArray * monkeys;
- (id)initWithNumberOfMonkeys:(int)howMany;
- (void)dealloc;
@end
MonkeyRanch.m
@implementation MonkeyRanch
@synthesize monkeys;
- (id)initWithNumberOfMonkeys:(int)howMany {
if ((self = [super init]) == nil) { return nil; }
monkeys = [[NSMutableArray alloc] initWithCapacity:howMany];
for (int index = 0; index < howMany; index++) {
Monkey * newMonkey = [[Monkey alloc] init];
[newMonkey setRanch:self];
[monkeys addObject:newMonkey];
[newMonkey release];
}
return self;
}
- (void)dealloc {
[monkeys release];
}
@end
Использование:
#import "MonkeyRanch.h"
MonkeyRanch * theRanch = [[MonkeyRanch alloc] initWithNumberOfMonkeys:3];
...
[theRanch release];