iOS 学习笔记--类属性(Property)、Property的attribute、点语法、实例变量等的联系
@property和实例变量
下面的代码里,ViewController类有个name属性,由于苹果将默认编译器从GCC转换为LLVM(low level virtual machine),所以从此就不再需要为属性声明实例变量了。
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
{
NSString *name;
}
@property (nonatomic, copy)NSString* name;
@end
也就是说,只要你已经声明属性name了,在编译时,编译器会在.m
文件里自动生成一个_name的实例变量,以供使用,就不需要声明实例变量name了,*{NSString name;}**这段代码就不必要写了,而在.m文件里就可以直接使用_name来调用这个属性
@property的作用
声明属性,让编译器在.m文件里生成_propertyName 对应的实例变量;生成实例变量对应的setter和getter方法,至于.m文件中的@synthesize name;
就不要写了,因为@synthesize name;
的作用就是为实例变量生成setter和getter方法,现在既然@property已经把所有的工作都干了,就没必要多此一举,反而显得代码冗余。
self.name 点语法的使用
self.name 既可以表示setter方法也可以表示getter方法,注意区别,请看下面的代码
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, readonly)NSString* name;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *newStr = self.name;
NSLog(@"%@",newStr);
// self.name = @"赋值";
}
@end
细心点就会发现区别,代表getter方法的时候是要用到这个属性的时候,或者说是获取的时候,而代表setter方法的时候就是赋值的时候,或者说是设置这个属性的时候,上面的代码中注释掉的那行,解注释就会报错,因为属性的属性为只读,也就是只能获取不能设置,也就没有setter方法,后面会讲到属性(property)的属性(attributes)
_name和点语法的使用区别
注意_name的使用没有调用setter方法或者getter方法,而是直接获取属性,所以在setter或者getter方法的时候注意情况,避免使用点语法导致死循环。参考setter方法的实现,代码如下,可以想一下把代码里的_name换成self.name会出现什么情况
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, copy)NSString* name;
@end
@implementation ViewController
-(void)setName:(NSString *)name
{
if (_name != name) {
[_name release];
_name = [name copy];
}
}
@end
属性(property)的属性(attributes)
见本人另一篇博文:http://blog.csdn.net/qq_28125515/article/details/50249489
私有属性
和上面的属性声明不同,在.m里面声明的属性也就只能在类内部使用,外部是访问不到的,而在.h文件里面声明的属性在类外部和内部都能使用。这点很基础的东西。
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, readonly)NSString* name;
@end
@implementation ViewController
@end