2011-08-20 1 views
3

Можно создать дубликат:
check retain countПроблема с хранением/выпуском. Разъяснение необходимости

Как я играл с retain, release подсчетов, я столкнулся с ситуацией, я не могу объяснить. Пожалуйста, помогите мне лучше понять:

  • Существует класс O. Он не содержит переменных и ничего не делает.
  • Существует класс графа. Он инициализирует приращения O и декрементирует рассчитывает на это
  • Существует ПИ СИБ с 2-мя кнопками: Сохранить и отпустите

enter image description here

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    o = [[O alloc]init]; // At this moment [o retainCount] is 1 as expected 
    .... 

Для каждого doRetain, подсчитывает приращения, как и ожидалось

- (IBAction)doRetain:(id)sender { 
    [o retain]; 

    NSString *result = [[NSString alloc] initWithFormat:@"%d", [o retainCount]];  
    [label setText: result]; 
    [result release]; 

} 

Всякий раз, когда вызывается освобождение, количество уменьшается

- (IBAction)doRelease:(id)sender { 
    [o release]; 

    NSString *result = [[NSString alloc] initWithFormat:@"%d", [o retainCount]]; 
    [label setText: result]; 
    [result release]; 

} 

Рассмотрим 1 сохраняет и 2-релизы

enter image description here

  1. Мы начнем с сохранением графом 1, после последовательности Alloc инициализации
  2. следует инструкции сохранить счетчик доходит до 2
  3. Затем мы уменьшаем количество, и оно уменьшается до 1
  4. После h следующее уменьшение ..... похоже, ничего не делает Сохранение счета еще 1
  5. Этот выпуск относится к плохой памяти и приводит к сбою приложения.

Пожалуйста, помогите мне понять это поведение

ответ

4

Если сохранить отсчет 1 и отпускания, объект больше не действует, и свойство releaseCount не имеет смысла (и результаты которых непредсказуемы).

Кроме того, я знаю, что это тест, но вы создаете свои строки с помощью «alloc», но не выпускаете их.

При работе с освобождением и удержанием вы несете ответственность за освобождение ваших СОБСТВЕННЫХ удержаний. Другие объекты могут выполнять сохранение на рассматриваемом объекте, и они, в свою очередь, освободят их.

Если вы получаете объект, используя метод, содержащий слова alloc, copy или create, есть подразумеваемая retain на указанный объект. В противном случае вы можете предположить, что объект исчезнет после текущего цикла цикла, поэтому, если вы хотите висеть на копии объекта, вам необходимо выполнить сохранение. Когда вы закончите с объектом, выполните выпуск.

+0

Это имеет смысл. Спасибо Дагу – JAM

1

Как уже упоминалось в другом недавнем посте вы никогда не должны действительно использовать функцию [retainCount]!

check retain count

+0

Ну, тогда ... как вы отслеживаете свои учетные записи? – JAM

+1

У вас нет. Вы в первую очередь управляете памятью. – jtbandes

+1

Я согласен, что вы никогда не должны использовать их для своего приложения, но они полезны для понимания того, как все работает. И @mac - вы НИКОГДА не используете счетчик хранения, чтобы определить, следует ли выпустить экземпляр. Я расскажу о своем ответе. –

2

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

  • вы подкласс NSObject (или создать свой собственный корневой класс)

  • не передать свой объект в любой системные интерфейсы на всех

  • не используют autoreleaseкогда

После того как вы нарушили любые этих правил, счетчик удержания становится деталью реализации, значение которой находится вне вашего контроля. Конечно, в простых случаях это будет относительно непротиворечиво. Пока это не так, и тогда вам остается отлаживать что-то, основанное на ложных предположениях, используя инструменты, которые являются неточными.

I.e.

не вызывайте keepCount!

cocoa memory management guide точно определяет, как следует сохранять и выпускать хранилища.

Вы должны рассматривать счетчик удержания как дельта; операция оставит его неизменным или увеличит или уменьшит его. Если вы увеличите его, вы должны уменьшиться, чтобы отказаться от владения. Абсолютное значение не имеет значения.