Авторелизный пул Objective-C не освобождает объект - PullRequest
3 голосов
/ 07 мая 2010

Я очень новичок в Objective-C и читал через управление памятью. Я пытался немного поиграться с NSAutoreleasePool, но каким-то образом он не выпустит мой объект.

У меня есть класс с установщиком и получателем, который в основном устанавливает имя NSString *. После освобождения пула я попытался NSLog объект, и он все еще работает, но я думаю, что это не должно?

@interface TestClass : NSObject
{
    NSString *name;
}

- (void) setName: (NSString *) string;
- (NSString *) name;


@end

@implementation TestClass   

- (void) setName: (NSString *) string
{
        name = string;
}  

- (NSString *) name
{
    return name;
}

@end

int main (int argc, const char * argv[]) {

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

TestClass *var = [[TestClass alloc] init];

[var setName:@"Chris"];
[var autorelease];
[pool release];

// This should not be possible?
NSLog(@"%@",[var name]);


return 0;
}

Ответы [ 2 ]

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

Когда вы отпускаете указатель var, вы сообщаете ОС, что указанная память доступна для перераспределения.Указатель по-прежнему указывает на эту память, и пока он не будет перераспределен, он по-прежнему содержит остатки вашего объекта.Как только он будет перераспределен, попытка вызвать метод name больше не будет работать.

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

Ваш код имеет несколько проблем.Во-первых, вы не делаете ни copy, ни retain строку, сохраненную в переменной экземпляра name.Таким образом, если строка освобождается тем, кто сохранил ее в свойстве, у вас останется свисающая ссылка.Вы должны сделать

- (void) setName: (NSString*) aName {
    if( name != aName ) {
        if( name ) [name release];
        name = [aName retain];    // or copy
    }
}

или использовать свойства с самого начала.

Кроме того, если вы храните ссылки на объекты в переменных экземпляра, вы должны предоставить правильное определение метода dealloc:

- (void) dealloc {
    self.name = nil;
    [super dealloc];
}

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

...