Точката в началото може да бъде малко подвеждаща.
Сеттерът
В реда, който сте публикували тук
self.scale = scale;
не присвоявате на локална променлива. Всъщност вие изпращате съобщението -setScale:
до self
. Този ред е еквивалентен на
[self setScale:scale];
Тъй като извиквате -setScale:
от -setScale:
, получавате тази безкрайна рекурсия.
Това, което трябва да направите, е да зададете променлива на екземпляр във вашия сетер (вместо да извиквате вашия сетер от самия себе си). Обикновено само с писане
@property (nonatomic) CGFloat scale;
създадохте променлива на екземпляр _scale
. Въпреки това, тъй като сте отменили и -scale
и -setScale:
, тази променлива на екземпляр няма да бъде създадена. Следователно ще трябва сами да добавите променливата на екземпляра. В декларацията на вашия клас @interface
(или алтернативно, в разширение на клас @interface
)
//If adding the instance variable to the class declaration:
@interface MyClass : Superclass
{
//....
CGFloat _scale;
}
//....
@end
След като направите това, достатъчно е да промените линията на
_scale = scale;
Добивачът
Има два други проблематични реда, които сте публикували, тези в инструмента за получаване. Първият е
return self.scale;
вътре - (CGFloat)scale
. Подобно на преди, тази нотация с точка не означава това, което може да мислите, че означава. Всъщност това означава
return [self scale];
Както и преди, това причинява безкрайна рекурсия. Второто е
if (!self.scale) {
Това е проблем по същата причина: изразът self.scale
, когато се оценява, е [собствен мащаб]. Отново, това причинява безкрайна рекурсия. Корекцията и на двете е да се замени self.scale
с _scale
, оставяйки ви с този инструмент за получаване:
- (CGFloat)scale
{
if (!_scale) {//Since CGFloat is not an object, this means <<if (_scale == 0) {>>
return DEFAULT_SCALE;
} else {
return _scale
}
}
По-добър начин
Вие вършите много повече работа тук, отколкото наистина трябва. Би било много по-добре да се възползвате от вашия инициализатор:
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
{
self.scale = DEFAULT_SCALE;
}
}
Това ще гарантира, че ако scale
не е зададено, то ще върне DEFAULT_SCALE
. Това ви позволява да елиминирате напълно гетъра (и, следователно, @synthesize
). Тъй като викате -setNeedsDisplay
в сетера, пак ще ви трябва.
- (void)setScale:(CGFloat)scale
{
if (_scale != scale) {
_scale = scale;
[self setNeedsDisplay];
}
}
person
Nate Chandler
schedule
31.10.2012