Я делаю свои первые шаги в Objective-C и столкнулся с небольшой, хотя и запутанной проблемой со статическим анализатором (Product-> Analyze) в XCode 4.1.Я создал простой класс дроби для рациональных чисел, который я выделяю и инициализирую следующим образом:
Fraction* f = [[[ Fraction alloc ] initWithNumerator:3 withDenomimator:5]
autorelease];
[ f print ];
, где print
- это метод, который просто использует NSLog
для отображения дроби, все работает отлично.Однако, если я разделю конструкцию alloc
/ init
на два утверждения (я понимаю, что это не идиоматично - я просто пытаюсь понять механизм) и использую руководство release
вместо autorelease
, дающее:
Fraction* f = [ Fraction alloc ]; // 1. Method returns an Objective-C object with
// a +1 retain count (owning reference)
[ f initWithNumerator:3 withDenomimator:5]; // 2. Object released
[ f print ]; // 3. Reference-counted object is used after it is released
[ f release ];
программа по-прежнему работает без ошибок, но анализатор XCode выдает предупреждения в комментариях.Почему XCode считает, что вызов init
приводит к освобождению объекта?
Думая об этом, пока я формулирую вопрос, я вижу, что две мои программы не совсем эквивалентны, потому что в первом фрагменте мой указатель f
- это результат вызова init
, тогда как во втором фрагменте это результат alloc
.Поэтому, изменив мой код на
Fraction* a = [ Fraction alloc ];
Fraction* f = [ a initWithNumerator:3 withDenomimator:5];
[ f print ];
[ f release ]; // or should it be [ a release ] ?
, он становится абсолютно эквивалентным, и статический анализатор перестает жаловаться.Так возможно ли, чтобы init
мог возвращать другой указатель, чем тот, который был передан ему из alloc
, а не просто , конфигурирующий память, которую он передал?С этим кодом я должен связать [ a release ]
с alloc
или [ f release ]
с init
?