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

属性

利用属性声明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的属性,做到赋值取值。

运行顺序

  1. 首先看 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
    }
    
  2. 判断属性,传入的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);
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值