美文网首页
细说@property(二)

细说@property(二)

作者: Chen_JF | 来源:发表于2019-01-03 20:57 被阅读0次

    @property合成和重写

    自动合成
    定义一个@property,在编译期间,编译器会生成实例变量、getter方法、setter方法,这些方法、变量是通过自动合成(autosynthesize)的方式生成并添加到类中。实际上,一个类经过编译后,会生成变量列表ivar_list,方法列表method_list,每添加一个属性,在变量列表ivar_list会添加对应的变量,如_name,方法列表method_list中会添加对应的setter方法和getter方法。

    动态合成
    既然有自动合成,那么相对应的就要有非自动合成,非自动合成又称为动态合成。定义一个属性,默认是自动合成的,默认会生成getter方法和setter方法,自动合成对应的代码是:

    @synthesize name = _name;
    

    上面这个代码时编译器自己生成的,不需要我们手动添加的。当然,如果我们需要动态合成,那么就需要自己写如下代码:

    @dynamic sex;
    

    上边这样代码就告诉编译器,sex属性的变量名、getter方法、setter方法由开发者自己来添加,编译器无需处理。

    当然,这时候你要去新建该对象,并调用该属性,获取值或者赋值。那么在编译的时候是没问题的,同样,运行也是一样没问题的,但当代码执行到这一行的时候,程序就会崩溃,崩溃信息是:
    [Student setSex:]: unrecognized selector sent to instance 0x60000217f1a0

    也就是说,该对象属性sex没有setterr方法,所以找不到setSex该方法,这也就是动态合成和自动合成的最大区别。动态合成需要开发者自己来写属性的setter、getter方法。当然,使用了@ dynamic后,编译器也不会自动生成遍历,因此你还需自己手动定义相应的变量,如_sex变量。

    重写setter、getter方法的注意事项
    按照上面需求,我们重写属性name的setter和getter方法一下:

    - (void)setName:(NSString *)name
    {
        NSLog(@"rewrite setter");
        _name = name;
    }
    
    - (NSString *)name
    {
        NSLog(@"rewrite getter");
        return _name;
    }
    

    但是编译器还是会提示错误,错误信息为:

    Use of undeclared identifier '_name'; did you mean 'name'?

    没有_name变量?我们没声明@dynamic,那么默认就是@ autosynthesize,那为什么没有_name变量呢?而且,当我们把setter或者getter其中一个方法注释掉,只保留一个方法,那就不会有错误的,为什么呢?

    当然,还是编译器做了一些处理。对于一个可读写的属性来说,当我们重写了它的setter、getter方法时,编译器会认为开发者想手动管理@property,此时会将@property作为@dynamic来处理,因此也就不会自动生成变量了。当然,也有解决办法,就是将显示的属性和一个变量绑定:

    @synthesize name = _name;
    

    这样就不会出错了。如果一个属性是只读的时候,重写getter方法时,编译器也会认为该属性是@dynamic。所以各位在重写getter、setter方法时,注意下是否有编译的问题。

    getter方法千万不可用self
    有经验的开发者都应该知道这一点,在getter方法中是不能使用self的,比如:

    - (NSString *)name
    {
        NSLog(@"rewrite getter");
        return self.name;  // 错误的写法,会造成死循环
    }
    

    原因代码注释中已经写了,这样会造成死循环。这里需要注意的是:self.name实际上就是执行了属性name的getter方法,getter方法中又调用了self.name, 会一直递归调用,直到程序崩溃。

    相关文章

      网友评论

          本文标题:细说@property(二)

          本文链接:https://www.haomeiwen.com/subject/bcbqrqtx.html