Objective-C:用实例变量覆盖Getter&Setter(使用_)
我正在学习Swift编程语言,在此期间我有时会与旧的Objective-C编程语言及其代码联系。Objective-C:用实例变量覆盖Getter&Setter(使用_)
我是一个绝对的初学者,因此我有一些问题可以更好地理解Setter和Getter。
所以,我知道我可以通过大括号在.h文件中创建一个实例变量,但通常我使用属性。这些属性由实例变量支持,并自动提供Getter和Setter方法。
例子:
车辆的.h文件:
@interface Vehicle : NSObject
@property int myProperty;
@end
因为我创造了这个属性我没有申报getter和setter方法在vehicle.m文件,因为它们是由编译器自动创建。所以我可以创建一个车辆对象,设置并获得价值。
例
的main.m
Vehicle *myvehicle = [[vehicle alloc] init];
[myvehicle myProperty] // myvehicle.myProperty
[myvehicle setMyProperty : 10] // myvehicle.myProperty = 10;
现在,我读了它可以覆盖自动创建Getter和我创造财产 “myProperty的” 的setter方法。当声明我自己的Getter和Setter版本时,我必须在vehicle.h和vehicle.m文件中声明两个方法。在vehicle.m文件中,我不使用self关键字调用对象,而是使用它自动创建的实例变量(_myProperty)。这样对吗?
我试过了,但总是得到一个错误,我不知道为什么,什么是重点。
例
车辆的.h文件:
@interface Vehicle : NSObject
@property int myProperty;
-(int) myProperty; //my new Getter method
-(void) setMyProperty: (int)updatedMyProperty; //My new Setter method
@end
车辆.m文件:
@implementation Vehicle
-(int) myProperty {
if (! _myProperty) {
_myProperty = NO;
}
return _myProperty;
}
-(void) setMyProperty: (int)updatedMyProperty {
if (_myProperty == updatedMyProperty) return;
_myProperty = updatedMyProperty;
}
@end
我总是得到错误 “使用未声明的标识符的” 和我不不知道为什么。如果我理解正确,我不必使用@synthesize声明ivar或其名称,因为编译器会自动为我创建名为_myProperty的ivar。当我想改变伊娃的名字时,我只需要使用@synthesize。
我不知道为什么我卡住了,重点是什么。你能解释一下吗? 在此先感谢!
如果你实现了所有的存取方法,编译器将不再为你自动合成ivar。在这种情况下,你必须自己明确地这样做。例如。
@synthesize myProperty = _myProperty;
这只在手动实现所有存取方法时才有必要。原因是编译器足够聪明,知道如果你接管访问器方法,你可能不需要伊娃,也就是说你可能会做一些完全不同的事情,例如,计算某些其他属性的值,设置/从某个不同的商店中获取值等。您可能希望编译器综合ivar(在这种情况下,您添加了以上@synthesize
语句),但实现访问者的可能性方法,因为没有需要支持伊娃(在这种情况下,你会省略上述@synthesize
声明)。
。不管怎么样,你简单的例子住,你喜欢的东西:
@interface Vehicle : NSObject
@property (nonatomic) int myProperty; // if you don't write atomic accessor methods, you really should be explicit that this is nonatomic
// as an aside, even if you implement accessor methods, you don't have to declare them here
//
// -(int) myProperty; //my new Getter method
// -(void) setMyProperty: (int)updatedMyProperty; //My new Setter method
@end
而且
@implementation Vehicle
// since you implemented all of the accessor properties, you have to manually synthesize the ivar
@synthesize myProperty = _myProperty;
- (int) myProperty {
// do whatever you want here; note, the following doesn't make sense
//
// if (! _myProperty) {
// _myProperty = NO;
// }
return _myProperty;
}
- (void)setMyProperty:(int)updatedMyProperty {
if (_myProperty == updatedMyProperty) return;
_myProperty = updatedMyProperty;
}
@end
显然,有以书面形式在上面的例子中,这些特定的访问方法是没有意义的,因为你没有提供任何新功能,所以你不会。您只需利用自动合成的存取器方法即可。
但是在那些你真的需要编写自己的存取方法的情况下,你必须明确告诉编译器是否需要它来为你合成ivar。
感谢您帮助和回答Rob!这真的帮助我了解幕后发生的原因和后果。在重写getter和setter时,我不得不在我使用的书中声明合成我的伊娃。所以,总结一下:在大多数情况下,我不需要综合任何东西。如果我想重写一个,getter或setter因为我想实现更多的代码,我不必做任何重写。如果我想覆盖两者,我必须手动合成伊娃,但正如我之前所说,在大多数情况下,没有必要这样做。再次感谢! – Ari
如果使用nonatomic属性,则可以覆盖getter或setter或两者。编译器会照顾其余的。
@property (nonatomic) int yourInt;
然后
-(int)yourInt
{
// do something
return _yourInt;
}
-(void)setYourInt:(int)someInt
{
// do something
_yourInt = someInt;
}
的注释写信getter或setter在.m文件到的这些差异:
_yourInt; //access variable directly
[self yourInt]; // use getter method
_yourInt = 4; // set vsriable directly
[self setYourInt:4]; // use setter method
我没有投票,但有两件事:首先,'getYourInt'方法应该是'yourInt'。 Objective-C不像其他语言中那样为getter使用'get'前缀。事实上,这个拼写错误是你的例子可能工作的唯一原因,因为你没有实现所有的访问器方法,并且Xcode只有在你实现了所有的访问器方法时才会绕过伊娃综合。其次,“原子”的规范是不相关的。 (实际上,当你忽略原子性限定符时,假定为'atomic'。) – Rob
感谢您的澄清! –
好。但问题是现在你已经正确实现了'yourInt'和'setYourInt',这个ivar,'_yourInt'将不再为你自动合成。事实上,这是OP的问题,也就是为什么它不能自动合成。 – Rob
无关的,但上述你有'[myvehicle setMyProperty = 10] '。显然这应该是'[myvehicle setMyProperty:10]'。 – Rob