Разница между @property и ivar в Xcode 4.5
Раньше я всегда видел пример использования свойств и iVars, как это...
Внутри SomeClass.h
@interface SomeClass : NSObject {
NSString *_someString;
}
@property NSString *someString;
@end
Затем в SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
@synthesize someString = _someString;
@end
Совсем недавно (в видеороликах WWDC 2012) я слышал, что нам больше не нужен @synthesize
, и он рекомендовал просто использовать @property
без связанного с ним iVar.
Итак, вышесказанное изменилось бы на...
SomeClass.h
@interface SomeClass : NSObject
@property NSString *someString;
@end
SomeClass.m
#import "SomeClass.h"
@implementation SomeClass
@end
Это просто использование @property
и no ivar. Это имеет смысл, и я использовал его.
Однако я также видел примеры...
SomeClass.h
@interface SomeClass : NSObject
@end
SomeClass.m
#import "SomeClass.h"
@interface SomeClass () {
NSString *someString;
}
@end
@implementation SomeClass
@end
В этом они просто имеют частный iVar
и не @property
.
И какая разница? Я понимаю, что @property
также предоставляет методы доступа, но вам не нужно переопределять методы доступа. Вы можете просто использовать устройства доступа по умолчанию.
Итак, когда вы будете использовать @property, а не ivar, и когда вы будете использовать только ivar, а не @property
? И почему бы вам просто не избавиться от иваров и просто использовать @properties
? Если они должны быть закрытыми, просто используйте их внутри расширения интерфейса в .m.
Быстрое редактирование в ответ на ответ об управлении памятью. Я использую ARC, и для меня кажется, что я больше контролирую управление памятью с использованием strong
и weak
@properties
, чем с iVars.
Надеюсь, этот вопрос достаточно ясен.
Спасибо
Ответы
Ответ 1
В общем, вы всегда можете использовать свойства. Если у вас есть свойство "присваивать", вы можете использовать ivar, потому что вам не нужно управление памятью в ваших getters/seters. Но если вы должны сохранить объекты, просто неудобно использовать ivars, потому что вы должны вручную сохранить/освободить их, пока свойства сделают это для вас.
Также, если вы используете ivars, у вас нет контроля над настройкой/получением значений. В общем, плохо использовать практические поля вместо геттеров или сеттеров. Например, это не нормально, если вы можете установить отрицательное значение для поля, в котором хранится возраст человека.
И вы не можете использовать KVO с ivars
Ответ 2
Я думаю, что это зависит от того, что у вас есть доступ к общедоступным ivars с синтаксисом ->
.
Возможно, ранее, если вы объявляете свойство readonly без @private
ivar, вы можете получить доступ
к нему ivar с синтаксисом "->
". (возможно, его разрывы инкапсуляции).
Но теперь, если вы объявите что-то вроде этого
{
@private NSArray *a;
@protected NSArray *b;
@public NSArray *c;
}
@property (nonatomic, retain) NSArray *d;
Доступ к "->
" доступен только для "c
" ivar, просто попробуйте этот код.
с a, b и d это будет предупреждение или ошибка.
Если это как-то поможет, я буду рад.