为什么需要声明具有相同名称的ivar和属性?

时间:2013-03-02 09:25:14

标签: objective-c ivar

在Xcode 4.4之前的大多数项目中,我意识到开发人员同时声明了一个同名的ivar和一个属性。实施例

@interface SecondViewController : UIViewController
{
     NSString *string;
}

@property (strong, retain) NSString *string;

所以我不知道为什么?

2 个答案:

答案 0 :(得分:7)

只是风格问题,习惯于过去编译器的行为。

现在在较新的编译器中,这不是必需的。一旦你创建了一个属性,就会在场景后面创建一个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

答案 1 :(得分:1)

我不能为别人说话,但我不会使用相同的名字。如果我确实声明了一个实例变量,那么它带有一个前导下划线,所以如果我指的是实例变量或者setter / getter方法,那就显而易见了。

使用Xcode 4.4+,您不需要声明实例变量或调用@synthesize,编译器将自动创建一个带有前导下划线的实例变量,并为您提供setter / getter方法。 / p>

但是我认为这个机制不是一个好主意,因为它鼓励开发人员公开不应该暴露的类的属性。

例如,这取自开始iOS 6开发

@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推出了新功能,以便他们能够在更短的时间内完成他们想要的工作(当您只需将插座拖到标题时,输入很少文件,并为您提供声明和实现框架。