您的位置:首页 > 其它

随意细解:OC -- 属性、点语法、KVC

2015-11-04 21:20 302 查看

属性

利用属性声明set、get方法。学习阶段,使用MRC,并在 .m 文件中练习get、set方法的完整实现。

读写类属性:

readonly 只读 (系统就不会默认生成set方法)

readwrite 读写 (如果什么都不写,默认就是可读写)

setter 设置指定的set方法默认生成的方法名

getter 设置指定的get方法默认生成的方法名

@property ( getter = isOpen) BOOL open;


原子性控制:

nonatomic 没有实现多线程同时访问一个变量的操作保护

atomic (如果什么都不写,默认的)添加了对多线程的保护操作。虽然安全,但是大量耗费系统资源,并且这个资源是不必要浪费的,所以一般使用nonatomic。

语义设置:

注意:创建工程 默认是ARC状态(自动管理内存)。在工程的设置中,将Objective-C Automatic Reference Counting 的 YES 改为 NO,手动管理内存 MRC。

get、set方法的完整实现:

assign 可以set、get方法的实现,是直接赋值。一般用来声明基本数据类型时候使用。

默认属性的实现关键字 @synthesize

@synthesize name = _name;
// 等号前代表声明的属性的名称
// 等号后代表要赋值的成员变量的名称

- (void)setName:(NSString *)name{
_name = name;
}
- (NSString *)name{
return _name;
}


retain set、get方法实现,内部实现对内存管理的优化,对象类型声明为retain。

@synthesize name = _name;

- (void)setName:(NSString *)name{
if ( _name != name){
[_name release];
_name = [name retain];
}
}
- (NSString *)name{
return [[_name retain] autorelease];
}


copy 与retain一样,但是声明为copy 有一个先决条件:必须遵守NSCopying协议,并且实现其方法。

@synthesize name = _name;

- (void)setName:(NSString *)name{
if ( _name != name){
[_name release];
_name = [name copy];
}
}
- (NSString *)name{
return [[_name retain] autorelease];
}


代码演示:

声明属性代表系统默认帮咱们实现了 setter和getter方法,并且实例变量为 _name

@property (nonatomic, retain) NSString *name;


点语法

提供了一个快捷的访问属性一种方式,快捷调用set、get方式。

等号左边调用的是set方法,赋值用的。等号右边调用的是get方法,取值用的。假设有Student类:

stu.name = @"haha";
stu.name = stu.sex;
NSLog(@"%@", stu.name);


KVC

间接方法,访问stu的属性,做到赋值取值。

运行顺序

首先看 setValue: 的参数是不是一个对象,因为必须要是对象类型,所以如果不是对象类型,例如基本数据类型,要用NSNumber / NSValue将类型转换为对象。

[stu setValue:18 forKey:@"age"];


是错的,应该将NSInteger 转换为 NSNumber:

NSNumber *num = [NSNumber numberWithInt:18];
[stu setValue:num forKey:@"age"];


或者使用语法糖:

[stu setValue:@18 forKey:@"age"];


另外:setValue:后也可以填 nil 。

[stu setValue:nil forKey:@"age"];


为了不使程序崩溃,必须在类中重写- (void)setNilValueForKey:(NSString *)key方法:

- (void)setNilValueForKey:(NSString *)key
{
NSLog(@"%@", key);
// 捕获到参数value是空的对应的key
}


判断属性,传入的key的查找顺序为:_key 、 _isKey 、key 、isKey 。如果传入的 key 找不到一样的属性,程序会抛出异常而崩溃,所以应该重写- (void)setValue:(id)value

forUndefinedKey:(NSString *)key方法。

[stu setValue:@"ddddd" forKey:@"name1"];


Student类中没有 name1 的实例变量,所有程序会崩溃。要用间接赋值的保护方法:

- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
// 捕获间接访问属性时 填错的key和value
NSLog(@"%@  %@", value, key);
// 如果使用间接访问,那么,必须实现这个方法
}


常用方法

setValue:forKeyPath:方法

forKeyPath这个方法,相当于跨一级去间接访问属性,是访问本类中属性的属性。通过这个方法去访问的话,需要传入一个路径,按填的这个路径 一级一级的进行查找。

例如:在Student类中有Phone类的对象作为实例变量

[stu setValue:@"hello" forKeyPath:@"phone.name"];


setValuesForKeysWithDictionary:方法

通过一个字典去间接赋值一个对象。

NSDictionary *dic = @{@"name":@"haha", @"sex":@"男"};
[stu setValuesForKeysWithDictionary:dic];
NSLog(@"%@  %@", stu.name, stu.sex);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: