2012-01-21 3 views
1

Я прочитал, что будет вызываться dealloc для объекта, только если значение count этого объекта станет равным нулю.iOS Утечки памяти

Я беру один объект для UIColor в интерфейсе раздела и установкой свойство

UIColor *currentColor; 
@property (nonatomic, retain) UIColor *currentColor; 

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

-(void)dealloc 
{ 
    [currentColor release]; 
    [super dealloc]; 
} 

Я сомневаюсь, как будет вызван dealloc для этого объекта, потому что я не отпускаю сохраненный объект где-нибудь. Заранее спасибо.

ответ

2

Я прочитал, что dealloc для объекта будет называться, только если сохранить счетчик этого объекта становится равным нулю.

Да.

Для простоты вызовите класс, который содержит currentColor объект как ColorContainer. Теперь, если вы создаете экземпляр ColorContainer, как следующее:

ColorContainer* containerColor = [[ColorContainer alloc] init]; // retain count + 1 

Сохранять счетчик для containerColor становится 1.

Предположим, вы создали экземпляр UIColor, и вы установили его в currentColor. В этом случае вы можете следовать двум различным путям. В первом вы можете создать экземпляр, например, следующий. Если вы используете метод экземпляра, например initWithRed:green:blue:alpha:, вы должны явно освободить память.

UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1 
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 because you use a retain policy 
[color release]; // retain count -1, now the referenced object has a retain count of 1 

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

containerColor.currentColor = [UIColor whiteColor]; // retain count +1 

Теперь предположим, что вы выпустили объект containerColor. Если счетчик удержания для containerColor равен 1, освобождая его от объекта, который его использует, он позволяет вызывать его метод dealloc и, следовательно, также отклонять объект, на который ссылается currentColor.

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

UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1 
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 
//[color release]; 

вы создаете утечку памяти (вы понимаете?).

Итак, при использовании retain, copy, init или new (это же из alloc-init), вы всегда должны называть своих коллег release или autorelease.

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

Итак, как метафора, вы можете думать в память, как дерево. Предположим, у вас есть родитель (containerColor) и ребенок (currentColor). Если родительский (с сохранением числа 1) освобождается, он вызывает вызов его метода dealloc и свободной памяти для своего объекта. Если в его методе dealloc вы освободите ребенка (с сохранением 1), он вызывает вызов его метода dealloc и свободной памяти. В случае, если у ребенка есть счет сохранения больше одного, вы вызываете утечку памяти.

Надеюсь, это поможет.

Редактировать

Для получения дополнительной информации вы можете прочитать About Memory Management. Так как iOS 5 Apple представила ARC. Автоматический подсчет ссылок - это механизм, который обеспечивает автоматическое управление памятью объектов Objective-C. Для информации см. Transitioning to ARC Release Notes.

+0

Здравствуйте, Flex, Большое спасибо за ваш ответ. – karthick

+0

Добро пожаловать! –

0

Вы должны только называть release об объекте, если вы его выделили (через alloc, copy или retain). Свойства с атрибутом retain автоматически будут выполнять управление памятью до тех пор, пока вы будете обрабатывать их правильно, например. используйте их только через self.currentColor. В зависимости от того, как вы создали цветной объект, вы могли или не могли использовать release, но вы всегда должны установить свойство nil в вашем методе dealloc. Два примера:

// If you use this (or some other way to get the color without alloc, copy or retain) 
// then you do not need to do any release 
self.currentColor = UIColor.blackColor; 
self.currentColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.2 alpha:1.0]; 

// On the other hand if you get it like this, you have to release/autorelease the object 
self.currentColor = [[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0]; 
[self.currentColor release]; 
// or better 
self.currentColor = [[[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0] autorelease]; 

// dealloc always the same 
-(void)dealloc{ 
    [currentColor release], currentColor = nil; 
    [super dealloc]; 
} 

Там находятся два важных факта здесь:

  1. Для каждого alloc, copy или retain, что ваши проблемы с кодом, вы должны выдать release или autorelease.

  2. Всегда используйте self.currentColor для доступа к объекту недвижимости, а не currentColor за исключением случаев освобождения. Дело в том, что при использовании self.currentColor система автоматически добавляет код управления памятью. Когда задан self.currentColor, он автоматически retain s и release с объектами. Только при окончательном освобождении вы должны установить переменную напрямую, для получения дополнительной информации см. this answer on the topic (спасибо Flex_Addicted).

+0

Вызов 'self.currentColor = nil;' метод dealloc может создавать проблемы, как это предлагается в [release-или-set-to-nil-keeped-members] (http://stackoverflow.com/questions/5358134/release -или-set-to-nil-retained-members) и в [MemoryMgmt Apple doc] (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html# // apple_ref/doc/uid/TP40004447-SW1) –

+0

Спасибо, довольно интересная мысль. Я отредактирую свое сообщение соответственно. –

+0

Добро пожаловать. –

2

При использовании сохранить сеттер для currentColor собственности вы retain, что объект, и если вы retain, copy или alloc памяти для объекта вы должны освободить его. -(void)dealloc лучшее место, чтобы сделать это

Смежные вопросы