2013-11-13 2 views
0

Из книги «Learn Objective-C на mac (второе издание)». Почему retain count является 2, но не 1 в следующем фрагменте кода: -Что такое учет в этом фрагменте кода?

- (void) setEngine: (Engine *) newEngine 
{ 
    [engine release]; 
    engine = [newEngine retain]; 
    // More BAD CODE: do not steal. Fixed version below. 
} // setEngine 

some_function 
{ 
    Engine *engine = [Engine new]; // count: 1 

    Car *car1 = [Car new]; 
    Car *car2 = [Car new]; 

    [car1 setEngine: engine]; // count: 2 But why? 1-1=0 (due to [engine release] 
           // in -(void) SetEngine.  
           // and after engine=[newEngine retain] retain count is 1. 

    [engine release]; // count 1 
    [car2 setEngine: [car1 engine]]; // oops! 

    return 0; 
} 
+3

Люди, которые на самом деле _use_ Сохранять количество почти всегда делают неправильные вещи :-) – paxdiablo

+1

[релиз] двигатель вызова для предыдущего выставиться двигателя. Используйте Arc, это намного проще. – Sk0prion

ответ

2

Прежде всего, пожалуйста, рассмотреть вопрос о переходе на ARC. В обычном программировании действительно нет причин для использования MRC.

Во-вторых, вы смешаете свои области. Помните, что в этом коде есть действительно пять указателей Engine*, но только один объект Engine.

В some_function:

  1. engine, локальная переменная
  2. car1.engine
  3. car2.engine

В setEngine: метода:

  1. engine, то Ивар
  2. newEngine параметр

Вот что происходит в коде:

  1. engine = [Engine new]; сохраняет двигатель, сохранить счетчик = 1
  2. [car1 setEngine:engine];
    • [engine release]; Освобождает двигатель ivar, который, вероятно, установлен на nil, и ничего не делает. сохраняют отсчет = 1
    • engine = [newEngine retain]; Сохраняет двигатель, сохранить счетчик = 2
  3. [engine release]; отпускает двигатель, сохраняют Count = 1
  4. car2 setEngine:engine];
    • [engine release]; Выбросы двигателя ИВАР автомобиля, который, вероятно, набор до nil, и ничего не делает. сохранить счетчик = 1
    • engine = [newEngine retain]; Сохраняет двигатель, сохранить счетчик = 2

Теперь, пожалуйста, сделайте себе одолжение и пусть подсчет ссылок компилятор ручки для вас.

+0

Я знаю об ARC. Я только пытаюсь понять управление памятью. [выпуск двигателя]; Освобождает двигатель ivar, который, вероятно, установлен на ноль и ничего не делает. сохранить count = 1 - почему сохранить count до 1, если мы его выпустим? Так -1 может быть ?? Предположим, это невозможно. И небольшое объявление, я нашел ссылку на мой вопрос после того, как его спросили: «Исправлена ​​ошибка чтения книги« Цель Objective-C на Mac »или плохой памяти?» - так может быть ошибка в этой книге? http://stackoverflow.com/questions/7374475/errata-on-learn-objective-c-on-the-mac-book-or-bad-memory-understanding – user2553675

+0

@ user2553675 Это не ошибка. Указатель 'engine' в методе' setEngine' является другим указателем, чем указатель 'engine' в' some_function'. Разная область действия, разные указатели. Вы должны больше узнать о том, как работают функции/вызовы методов, так как это ваше замешательство. Вы прекрасно понимаете концепцию подсчета ссылок. – godel9

+0

Возможно, я понял. В методе setEngine не переменный движок из основного scop освобождается, но экземпляр var в классе Car. И в [автомобиль2 комплектEngine: [автомобиль1 двигатель]]; передается экземпляр двигателя автомобиля var, который теперь равен нулю. Спасибо. – user2553675

0

Пожалуйста, проверьте мои комментарии

- (void) setEngine: (Engine *) newEngine 
{ 
    // setEngine: is method defined inside Car. 
    // so engine reference is retained by Car 
    // and it should be released when Car is released 
    // ie. in car dealloc method 
    [engine release]; 
    engine = [newEngine retain]; 
    // More BAD CODE: do not steal. Fixed version below. 
} // setEngine 

- (void)dealloc{ 
    [engine release]; // Retaining count is reducing 
    [super dealloc]; 
}  


some_function 
{ 
    Engine *engine = [Engine new]; // count: 1 

    Car *car1 = [Car new]; // +1 for car1 
    Car *car2 = [Car new]; // +1 for car2 

    [car1 setEngine: engine]; // count: 2 But why? 1-1=0 (due to [engine release] 
           // in -(void) SetEngine.  
           // and after engine=[newEngine retain] retain count is 1. 

    [engine release]; // count 1 
    [car2 setEngine: [car1 engine]]; // count 2 - Here Car2 retaining same 
            //engine retained by Car1. So retain 
            //count of engine increases. 

    [car1 release];// count 1 
    [car2 release];// count 0 


    return 0; 
} 
Смежные вопросы