2

Я протечки память об этом:Возвращение объектов с autorelease, но я до сих пор утечка памяти

мой пользовательский класс:

+ (id)vectorWithX:(float)dimx Y:(float)dimy{ 
return [[[Vector alloc] initVectorWithX:dimx Y:dimy] autorelease]; } 


- (Vector*)add:(Vector*)q { 
return [[[Vector vectorWithX:x+q.x Y:y+q.y] retain] autorelease]; } 

в приложение делегата I инициируют его:

Vector *v1 = [[Vector alloc] initVector]; 
Vector *v2 = [[Vector alloc] initVector];  
Vector *vtotal = [[v1 add:v2] retain]; 

[v1 release]; 
[v2 release]; 
[vtotal release]; 

Как это утечки? Я выпускаю или автоматически проверяю их. Приложение немедленно сработает, если я не сохраню их, из-за раннего выпуска, я думаю. Он также падает, если я добавлю еще один релиз.

+0

Вы надеваете 't нужно сохранить/автоопределить новый вектор в add, просто вернуть результат из [Vector vectorWithX: Y:]. Можете ли вы опубликовать код для initVector и т. Д.? –

+0

Большое спасибо за ответ, я уже удалил сохранение/авторекламу от добавления, но все еще течет. вектор инициализации: (синтезируется x и y) - (id) initVector {self = [super init]; if (self) {x = 0; y = 0; } return self; } – gok

ответ

2

Почему вы думаете, что у вас утечка памяти? Начните с этого. И какой объект вы сталкиваетесь при доступе? Это, скорее всего, скажет вам, к какому объекту относится ваше недодержанное. Если бы я должен был предположить, я бы заподозрил initVector, просто потому, что это очень странное имя для метода. Что оно делает? Почему он не называется просто «init»?

Это этот код с резьбой? Вы делаете намного больше удержания/авторекламы, чем это обычно уместно. Вам не нужно сохранять объект, чтобы удерживать его через текущий цикл событий. Вообще говоря, вы сохраняете только ivars, потому что это то, что вам нужно, через следующий цикл событий. Если у вас много вызовов, чтобы сохранить за пределами доступа, то вы почти наверняка неправильно управляете памятью. Выше должно быть:

+ (id)vectorWithX:(float)dimx y:(float)dimy 
{ 
    return [[[Vector alloc] initVectorWithX:dimx y:dimy] autorelease]; 
} 

- (Vector*)add:(Vector*)q 
{ 
    return [Vector vectorWithX:(self.x + q.x) y:(self.y + q.y)]; 
} 

... 

Vector *v1 = [[Vector alloc] initVector]; 
Vector *v2 = [[Vector alloc] initVector]; 
Vector *vtotal = [v1 add:v2]; 
... 
[v1 release]; 
[v2 release]; 

Лично я бы обрабатывать v1/v2 с autorelease, потому что я думаю, что это делает код более ремонтопригодны и понятно, но есть и другие школы мысли:

Vector *v1 = [[[Vector alloc] initVector] autorelease]; 
Vector *v2 = [[[Vector alloc] initVector] autorelease]; 
Vector *vtotal = [v1 add:v2]; 
+1

Эй, @ Rob, вы перевыполнили свои векторы в своем примере очистки (автореклама после инициализации, а затем специально выпущена в конце). –

+0

Я получил их обоих назад .... Спасибо. Исправлена. –

+0

@gok, глядя на ваш код в приведенном выше комментарии, метод, о котором идет речь, должен быть просто «init», а не «initVector». И вы должны убедиться, что используете аксессоры, а не напрямую обращаетесь к своим ivars. Не использование аксессуаров - причина ошибок памяти 1, как то, что вы видите. Да, я знаю, что это поплавки. Все равно используйте аксессоры. Вероятно, ваша фактическая утечка находится в другом месте; вероятно, во что-то еще, что сохраняет вектор. (Но почему вы считаете, что у вас есть утечка, кстати?) –