一, 属性
- 属性是 Objective - C 2.0定义的语法, 为实例变量提供了 setter,getter 方法的默认实现
- 能在一定程度伤简化程序代码,并且增强实例变量的访问安全性
1. 属性的声明: 使用@ property 声明属性
例如: @property NSString *name;
相当于在@interface 中声明了两个方法(setter, getter);
- (void)setName:(NSString *)name;
- (NSString *)name;
2. 属性的实现 : @syzthesize 实现属性
例如 :@syzthesize name = _name;
相当于@ implementation 实现了 setter, getter.
- (void)setName:(NSString *)name
{
.....
}
- (NSString *)name
{
......
}
二, 属性的属性
Objective - C 提供属性的目的目的是为了简化程序员编码
为属性提供了一些 关键字用以控制 setter, getter 的实现细节
这些关键字我们称为属性的属性 (attribute)
属性分三大类
第一类:读写性控制 (readonly, readwrite, setter, getter)
readonly, 只读属性,告诉编译器,只声明 getter 方法 无 setter 方法
例如:@ property (readonly)NSString *name;
readwrite, 可读可写,告诉编译器,既声明 setter , getter
例如:@ property (readwrite) NSString *name;
- (void)setName:(NSString *)name;
- (NSString *)name;
read 是读写性控制的 默认设置
第二类 :原子性控制 (nonatomtic, atomtic)
atomic. setter, getter 方法在多线程访问下是绝对安全的.即setter,getter 内部做了多线程访问处理,
原子性控制的 默认设置是 atomic.
nonatomic. 在 setter,getter 方法内部不会做多线程访问处理, 仅仅是普通的 setter,getter 方法
在程序发开中. setter, 和 getter 处处都在用,如果使用 atomic, 需要不断的对 setter,getter 加锁解锁以 保证线程访问安全性,但会很占用系统资源,降低系统性能
通常原子性控制.我们会设置为 nonatomic 某些属性需要线程安全的时候,才会去定义为 atomic
例如:@ property (readwrite, nonatomic) NSString *name;
第三类:语义设置 (assign, retain, copy)
assign : setter, getter 内部实现都是直接赋值
@property (nonatomic, assign) NSString *name;
// setter
- (void)setName:(NSString *)name
{
_name = name;
}
// getter
- (NSString *)name
{
return _name;
}
retain: setter,getter 的内部实现也回做内存优化
例如:@property (nonatomic, retain)NSString *name;
// setter
- (void)setName:(NSString *)name
{
if(_name != name) {
[_name = release];
_name = [name retain];
}
}
// getter
- (NSString *)name
{
return [[_name retain] autorelease];
}
copy: setter,getter 的内部实现也回做内存优化
例如:@ property (nonatomic, copy) NSString *name;
// setter
- (void)setName:(NSString *)name
{
if(_name != name) {
[_name release];
_name = [name copy];
}
}
// getter
- (NSString *)name {
return [[_name retain] autorelease];
}
属性的总结
如果属性是非对象类型的 例如 (int float等 基本数据类型) 属性的语义设置使用 assgin.
如果属性是对象类型,例如 (NSString, NSArray 等) 属性的语义关键字用 retain.
如果属性是对象类型并且向得到参数的 copy, 使用copy 关键字
属性就是一对 setter getter 方法.
点语法: 是 Objective -C 2.0 中定义的语法格式. 提供了一种便捷的属性访问方式
凡是符合系统默认 setter, getter 书写格式的方法都可以使用点语法
例如: [person1 setName:@"小强"];
点语法: person1.name = @"小强";
NSString *name = [person1 name];
点语法:NSString *name = person1.name
四, KVC
KVC(Key- Value - Coding), 键值编码, 是一种间接访问实例变量的方法
Key: 键, 用于表示实例变量
value: 实例变量对应的值
// 使用便利构造器创建 student 对象
// 字面量创建的是不可变的.放到可变数组中会有警告
NSMutableArray *array = [NSMutableArray arrayWithObjects:@(34), @(80), @(85), nil];
Student *student1 = [Student studentWithName:@"weidong" scoresArray:array age:12 num:3838438];
[student1 setAge:13]; // 通过 setter 方法修改属性的值
student1.age = 15; // 通过点语法给对象的属性赋值
student1.name = @"文彬";
student1.num = 250250250;
student1.scoresArray = [NSMutableArray arrayWithObjects:@(35), @(80), @(85), nil];
student1.scoresArray[0] = @(56.3);
// 通过 KVC 去访问实例变量 Key(forKey:后) 必须写属性名称(实例变量)
[student1 setValue:@"xiaohong" forKey:@"name"];
[student1 setValue:@(18) forKey:@"age"];
// 赋值
[student1 setValue:@(68.4) forKey:@"_heigth"];
// 通过 key 取 value 的值
NSLog(@"%@", [student1 valueForKey:@"_heigth"]);