随意细解: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);
相关文章推荐
- iOS开发小技巧:刷新UITableView
- Mail搭建
- 两个链表的第一个公共结点
- 根据给定的字节长度截取字符串
- Android自定义View构造函数详解
- 【搜索+状压DP】 HDU 3681 Prison Break
- JOS 轮转调度实现
- 串口Termios
- XMPP协议获取花名册(好友列表)
- 简单计算器
- HDOJ 题目2852 KiKi's K-Number(线段树求大于a的第k值)
- 51nod 1378:夹克老爷的愤怒 很好玩的一道树状dp
- 黑马程序员—Java基础—IO5
- 51nod 1378:夹克老爷的愤怒 很好玩的一道树状dp
- LA 1453 旋转卡壳
- iptables详解
- 客户端用HttpURLConnection向php服务器上传图片
- 关于Fragment懒加载的学习和使用+参数传递的方法
- 希尔排序
- 2015.11.4