Вы можете создать вычисляемый реквизит (например, parsedTabs) и удалить те вкладки, которые вы не хотите показывать, например:
parsedTabs() {
return this.tabs.filter(tab => tab.size);
}
Свойства являются просто методами set и методами считывания для ivars
и должен (почти) всегда использоваться вместо прямого доступа.
@interface APerson : NSObject {
// NSString *_name; // necessary for legacy runtime
}
@property(readwrite) NSString *name;
@end
@implementation APerson
@synthesize name; // use name = _name for legacy runtime
@end
@synthesize
создает в этом случае те два метода (не точных 100%):
- (NSString *)name {
return [[_name copy] autorelease];
}
- (void)setName:(NSString *)value {
[value retain];
[_name release];
_name = value;
}
Легко теперь различать ivars
и методы считывания/методы set. Средства доступа имеют self.
префикс. Вы не должны получать доступ к переменным непосредственно так или иначе.
Ваш пример кода не работает, как это должно быть:
_myVar = some_other_object; // _myVar is the ivar, not myVar.
self.myVar = some_other_object; // works too, uses the accessors
В целом я называю свои свойства тем же как мои переменные экземпляра; это - предположение по умолчанию что @property
синтаксис делает. Если Вы находите борьбу со значениями по умолчанию Вы делаете его неправильно (или Ваша платформа sux, который не имеет место для Cocoa/Cocoa-touch, по-моему).
Ошибка компилятора, которую Вы получаете, - то, потому что использование свойства всегда должно иметь ссылку на объект, даже в Вашей собственной реализации класса:
self.stuff = @"foo"; // property setter
[stuff release]; // instance variable
stuff = @"bar"; // instance variable
return self.stuff; // property getter
Я знаю, что многие программисты Cocoa не соглашаются, но я думаю, что это - плохая практика для использования свойств в реализации класса. Я видел бы что-то вроде этого:
-(void) someActionWithStuff: (NSString*) theStuff {
// do something
[stuff release];
stuff = [theStuff copy];
// do something else
}
чем это:
-(void) someActionWithStuff: (NSString*) theStuff {
// do something
self.stuff = theStuff;
// do something else
}
Я предпочитаю делать управление памятью максимально явно. Но даже если Вы не соглашаетесь, с помощью self.stuff
форма будет, подсказка в любом испытала программиста Objective-C, что Вы называете свойство вместо того, чтобы получить доступ к переменной экземпляра. Это - тонкий момент, который это легко для новичков замять, но после работы с Objective C 2.0 некоторое время это довольно ясно.
Называют синтезируемое свойство prop
на самом деле представлен двумя методами prop
(возвращение текущего значения свойства) и setProp:
(устанавливание нового значения для опоры).
self.prop
синтаксис является синтаксическим сахаром для вызова одного из этих средств доступа. В Вашем примере можно сделать любое из следующих для установки свойства myVar
:
self.myVar = @"foo"; // handles retain/release as specified by your property declaration
[self setMyVar: @"foo"]; // handle retain/release
_myVar = @"Foo"; // does not release old object and does not retain the new object
К свойствам доступа использовать self.propname
. К доступу переменные экземпляра используют просто имя переменной экземпляра.
Поскольку Apple резервирует префикс _ для себя, и поскольку я предпочитаю делать его более очевидным, когда я использую сеттер и когда я использую ivar, я принял Практика использования префикса i_ в моих ivars, например:
@interface MyClass : NSObject {
NSString *i_myVar;
}
@property (nonatomic, retain) NSString *myVar;
@synthesize myVar = i_myVar;
i_myVar = [input retain];
self.myVar = anotherInput;
[i_myVar release]
Поскольку очень важно знать, когда вы используете установщик и когда вы используете ivar,
Проблема с использованием стратегии @synthesize myVar = _myVar заключается в том, что я полагал, что написание такого кода, как:
myVar = some_other_object; // не работает.
Компилятор жалуется, что
myVar
не объявлен. Почему это так?
Потому что переменная myVar
не объявлена.
Этот оператор использует синтаксис для доступа к переменной, будь то переменная экземпляра или какой-либо другой тип. Как сказал вам rincewind, для доступа к свойству вы должны использовать либо синтаксис доступа к свойству ( self.myVar = someOtherObject
), либо явное сообщение методу доступа ( [self setMyVar: someOtherObject]
).
В противном случае вы пытаетесь получить доступ к переменной, а поскольку у вас нет переменной с именем myVar
, вы пытаетесь получить доступ к переменная, которой не существует.
Дон,
Согласно «правилам», вы должны вызывать Release для каждого копирования, распределения и сохранения. Так почему вы звоните в Release по разным вопросам? Предполагается ли, что он был создан с помощью Alloc, Copy или Retain?
Это поднимает другой вопрос: Вредно ли вызывать Release для ссылки на объект, если он уже был освобожден?