成员变量和属性(@property)的关系
成员变量的声明方法:
@interface Person : NSObject
{
NSString *_name;
NSString *_gender;
NSInteger _age;
}
@end
成员变量就是我们写在花括中的变量, 声明方法的括号中的NSString *_name; NSString *_gender;NSInteger _age; 都是成员变量。
实例变量 实例变量是成员变量的一部分,虽然_name和_age都是成员变量,但是它们是不同的,_name是一个对象指针(前面带*的),_name又被称之为实例变量,成员变量包含实例变量。 成员变量中除了_age这样的基本数据类型,其它的都是实例变量;
属性(@property)的声明方法:
@interface Person : NSObject
@property NSString *name;
@property NSString *gender;
@property NSInteger age;
@end
属性就是通过@property 定义的变量,xcode编译器会自动生成一个成员变量 NSString *_name; NSString *_gender;NSInteger _age;以及对应的setter和getter方法。
属性的特性是一些修饰符,影响属性对应的setter、getter方法的内部细节。
属性的特性第一类 读写性
1、readonly,只读,属性只生成了 getter方法,没有setter方法。 @property (readonly)NSString *gender;
2、readwrite,可读可写,属性既生成了setter、也生成了getter。读写性控制中,readwrite是默认的修饰符,所有属性,如果不加修饰,全部都是可读可写的。 @property (readwrite)NSString *name;
3、setter= ,修改setter方法的方法名
4、getter= ,修改getter方法的方法名
属性的特性第二类 原子性
1、atomic,原子性,默认修饰符,保证了实例变量在多线程情况下访问是安全的,通过不断的加锁解锁实现在同一时刻实例变量只能被一个线程访问。但是不断的加锁解锁会耗费大量的cpu性能,所以虽然是默认的,我们也不会采用
2、nonatomic,非原子性,属性常用的修饰符。
属性的特性第三类 语义特性,语义不同,直接决定了属性对应的setter、getter方法内部实现的不同。
1、assign,修饰的属性是非对象类型的。并且assign是默认的语义特性。
2、retain,所有对象类型的属性,都可以用retain来修饰。
3、copy,copy也是用来修饰对象类型的属性,但是一定要保证,代表属性类型的这个类,必须接收了NSCopying协议,而且实现了copyWithZone:方法。字符串通常用copy来修饰。
@private、@public 、 @protected
属性和成员变量可以被@private、@public 、 @protected 修饰
@private 表示这个类私有的 只允许该类内部和该类的对象访问,其它类和他的子类不累访问。
@protected 表示只允许该类和该类的子类访问。
@public 表示公共的,所有的对象都能访问。
怎么简单的理解getter和setter
setter:给外部提供的一个修改内部属性值的接口,调用setter方法可以做到修改内部属性值。
getter:外界提供的一个查看内部变量的接口。
self.name和 _name的区别: 前者:self.name = @"happy" 是通过调用setter方法设置属性值,而 NSString *str = self.name 就是通过调用getter 方法获取属性值; 后者:直接去访问成员变量;