在 Xcode 4.4 之前的大多数项目中,我意识到开发人员同时声明了一个 ivar 和一个具有相同名称的属性。例子
@interface SecondViewController : UIViewController
{
NSString *string;
}
@property (strong, retain) NSString *string;
所以我不知道为什么?
在 Xcode 4.4 之前的大多数项目中,我意识到开发人员同时声明了一个 ivar 和一个具有相同名称的属性。例子
@interface SecondViewController : UIViewController
{
NSString *string;
}
@property (strong, retain) NSString *string;
所以我不知道为什么?
只是风格问题,习惯于过去编译器的行为。
现在在较新的编译器中,这不是必需的。一旦您创建了一个属性,就会在后台创建一个 ivar 并对其进行合成。
编译器使用别名作为 _propertyName 进行综合,即使您可以选择更改此默认行为。
@interface AppDelegate : NSObject <NSApplicationDelegate>{
NSString *bigString;
}
@property(strong)NSString *smallString;
@end
@implementation AppDelegate
@synthesize smallString=bigString;
-(void)awakeFromNib{
self.smallString=@"hello";
NSLog(@"%@",self.smallString);
}
@end
我不能为别人说话,但我不使用相同的名字。如果我确实声明了一个实例变量,它带有一个前导下划线,所以如果我指的是实例变量或 setter/getter 方法,这很明显。
使用 Xcode 4.4+ 你不需要声明实例变量或调用@synthesize
,编译器会自动创建一个实例变量,带有前导下划线,并为你提供 setter/getter 方法。
但是我不认为这种机制是一个很好的主意,因为它鼓励开发人员公开不应公开的类的属性。
例如,这是从 iOS 6 Development 开始的:
@interface BIDViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIButton *button;
- (IBAction)buttonPressed:(UIButton *)sender;
@end
现在,虽然我知道您不想一次用太多概念混淆初学者,但您通过UIButton
向该视图控制器的用户公开对象和操作方法立即违反了面向对象封装,并且两者都不应该公开.
例如,如果使用类这样做会发生什么:
BIDViewController *vc = ...;
vc.button = nil;
或者
vc.buttonPressed(mySegmentedControl);
所有的地狱都崩溃了。现在,虽然有 1000 种方法可以破坏程序,但我们无法防御所有这些方法,但我们不想制作一个已经很弱的系统(Objective-C 在定义谁可以调用和不能调用一个方面提供的很少你的方法)较弱。
上面的实现最好使用私有实例变量和方法来完成,这两者都被 Interface Builder 尊重:
@implementation BIDViewController ()
{
IBOutlet UIButton *_button;
}
- (IBAction)_buttonPressed:(UIButton *)sender;
@end
并且任何使用类都将很难打破该模型。
但当然,这对于开发人员来说需要更多的思考和打字,因此 Apple 推出了新功能,以便他们可以在更短的时间内完成他们想要完成的工作(当您简单地将插座拖到头文件时,打字很少,两者都为您提供了声明和实现框架)。