美文网首页
细说@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(二)

    @property合成和重写 自动合成定义一个@property,在编译期间,编译器会生成实例变量、getter方...

  • 细说@property(三)

    @property修饰符 定义一个属性时,nonatomic、copy、strong、assign等被称作是关键字...

  • 细说@property(一)

    @property是什么? @property = 实例变量 + get方法 + set方法 上面这段代码,可能初...

  • 细说@property(五)

    copy和mutableCopy copy和mutableCopy之间的差异主要和深拷贝和浅拷贝有关,先看一下深拷...

  • 细说@property(四)

    copy和strong copy和strong的区别是面试中出现频率最高的,我们一般都知道,不可变对象属性修饰符使...

  • OC基础

    关于@property (1) @property的本质是啥编译器都帮你做了什么事儿详细说明(2) 关键字assi...

  • 面试题汇总

    ? 1. 基础 细说@property iOS基础面试题1(5.16) iOS基础面试题2 (5.24) 标哥(黄...

  • 细说Spring——IoC详解(XML配置一)

    在我们经过了: 细说Spring——IoC详解(一) 细说Spring——IoC详解(二) 细说Spring——I...

  • NSDictionary 细说

    NSDictionary细说(一)—— 整体了解NSDictionary细说(二)—— 字典的创建NSDictio...

  • NSString 简单细说

    NSString 简单细说(一)—— NSString整体架构NSString 简单细说(二)—— NSStrin...

网友评论

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

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