объектив-C 2.0 свойства и «удерживать»
-
19-09-2019 - |
Вопрос
Глупой вопрос, но зачем нам использовать «удерживать» при объявлении имущества? Разве это не сохраняется в любом случае, когда ему что -то назначено?
Глядя на этот пример, кажется, что объект автоматически сохраняется при выборе, так какой смысл?
#import "Fraction.h"
#import <stdio.h>
int main( int argc, const char *argv[] ) {
Fraction *frac1 = [[Fraction alloc] init];
Fraction *frac2 = [[Fraction alloc] init];
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// increment them
[frac1 retain]; // 2
[frac1 retain]; // 3
[frac2 retain]; // 2
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// decrement
[frac1 release]; // 2
[frac2 release]; // 1
// print current counts
printf( "Fraction 1 retain count: %i\n", [frac1 retainCount] );
printf( "Fraction 2 retain count: %i\n", [frac2 retainCount] );
// release them until they dealloc themselves
[frac1 release]; // 1
[frac1 release]; // 0
[frac2 release]; // 0
■ Вывод
Фракция 1 сохранить счет: 1
Фракция 2 сохранить счет: 1
Фракция 1 сохранить счет: 3
Фракция 2 сохранить счет: 2
Фракция 1 сохранить счет: 2
Фракция 2 сохранить счет: 1
Фракция сделки
Фракция сделки
Это сводит меня с ума!
Решение
Поведение свойства по умолчанию назначено, а не сохраняется. Это не то же поведение. Если ваше свойство предназначено для примитивного типа данных, например, Int, то назначение было бы правильно в использовании. Однако, если вы указываете (сохранить), а свойство указывает на указатель объекта, такой как объект NSOBject *, указателю присваивается адрес памяти объекта, и его количество сохраняется, увеличивается на один. Если ваша программа состоит из единственного, чем единственной основной функции, то ее цель трудно увидеть. Однако предположим, что у вашего класса был этот метод:
-(void)setMyArrayWithString:(NSString *)s{
myArray = [NSArray arrayWithObject:s];
}
Предположим, что Myarray определяется как nsarray *myarray и имеет правильный оператор @property (сохранить). Все работает нормально, пока метод не вернется. Это связано с тем, что объект, возвращаемый из NSArray, является авторелированным объектом. Если мы не сохраним его, это будет выпущено NSAutoreleAsePool, и мы не сможем его использовать (и мы получим неприятные ошибки и нарушения плохого доступа). Чтобы исправить это, мы можем сделать одну из двух вещей:
-(void)setMyArrayWithString:(NSString *)s{
self.myArray = [NSArray arrayWithObject:s];
// OR
myArray = [[NSArray arrayWithObject:s] retain];
}
Первое решение использует Self.myarray для использования определения @property. Этот код назначает, а затем сохраняет объект, чтобы мы не теряли его, когда функция возвращается. Второе решение устанавливает NSArray *Myarray Pointer вручную, а затем вручную сохраняет объект NSArray. В любом случае, NSAutoreLeasePool выпустит объект в конце функции, однако он не будет сработал, потому что у нас все еще есть удержание от более раннего сохраняющего его живым.