比较早期的ios我们为输出口同时声明了属性和底层实例变量
@interface MyViewController :UIViewController
{
UIButton *myButton;
}
@property (nonatomic, retain) UIButton *myButton;
@end
随着发展apple公司将默认编译器从GCC转换为LLVM(low level virtual machine),从此不再需要为属性声明实例变量了。因为LLVM发现一个没有匹配实例变量的属性,它将自动创建一个以下划线开头的实例变量。因此,我们不再为输出口声明实例变量。
@interface MyViewController :UIViewController
@property (nonatomic, retain) UIButton *myButton;
//系统在编译的时候会自动生成一个带有下划线的_myButton
@end
还可以self.myButton调用属性的getter/setter方法
关于成员变量
@interface MyViewController :UIViewController
{
NSString *name;
}
@end
self.name 是会提示使用 改成self->name 这就是区别(成员变量没有调用方法)
@synthesize 还有一个作用,可以指定与属性对应的实例变量,例如@synthesize myButton = xxx;那么self.myButton其实是操作的实例变量xxx,而不是_myButton了。
在实际的项目中,我们一般这么写.m文件
@synthesize myButton;
这样写了之后,那么编译器会自动生成myButton的实例变量,以及相应的getter和setter方法。注意:_myButton这个实例变量是不存在的,因为自动生成的实例变量为myButton而不是_myButton,所以现在@synthesize的作用就相当于指定实例变量;
如果.m文件中写了@synthesize myButton;那么生成的实例变量就是myButton;如果没写@synthesize myButton;那么生成的实例变量就是_myButton。所以跟以前的用法还是有点细微的区别。
二、类别中的属性property
类与类别中添加的属性要区分开来,因为类别中只能添加方法,不能添加实例变量。经常会在ios的代码中看到在类别中添加属性,这种情况下,是不会自动生成实例变量的。比如在:UINavigationController.h文件中会对UIViewController类进行扩展
@interface UIViewController (UINavigationControllerItem)
@property(nonatomic,readonly,retain) UINavigationItem *navigationItem;
@property(nonatomic) BOOL hidesBottomBarWhenPushed;
@property(nonatomic,readonly,retain) UINavigationController *navigationController;
@end
这里添加的属性,不会自动生成实例变量,这里添加的属性其实是添加的getter与setter方法。
注意一点,匿名类别(匿名扩展)是可以添加实例变量的,非匿名类别是不能添加实例变量的,只能添加方法,或者属性(其实也是方法)。
如何区别成员变量 属性 局部变量
@interface ViewController : UIViewController
{
//成员变量
NSArray *array1;
}
//属性变量
@property (nonatomic,strong) NSArray *array2;
@end
- (void)viewDidLoad
{
[super viewDidLoad];
array1 = [[NSArray alloc] initWithObjects:@"abcde", nil];
array2 = [[NSArray alloc] initWithObjects:@"123abc", nil];
{
// 局部变量
NSArray *array1 = [[NSArray alloc] initWithObjects:@"12345", nil];
}
NSLog(@"\narray1 : %@\n array2 : %@",array1,array2);
}
局部变量:是根据其生存周期定义的,在源文件中的array1,其生命周期是在以“{ }”为界限的代码块中,
成员变量:是用于一个区域内的临时变量。成员变量,本例中的是实例成员变量,是作用于整个类对象内的。
从生命周期来看,它比局部变量要长一些,但它默认是私有的,其他对象是无法访问到的。因此,一般自定义方法,作为一个接口让其他对象访问这个变量。因此,成员变量用于类内部,无需与外界接触的变量
成员变量默认是protected,一般情况下,非子类对象无法访问
虽然它的名称与成员变量相同,但不是同一个变量。