OC 中,覆盖属性会有怎么样的化学反应?

原创 2015年11月19日 18:01:18

首选须知:摘自:github上《招聘一个靠谱的iOS》面试题参考答案(上).md

 @synthesize和@dynamic分别有什么作用?

  1. @property有两个对应的词,一个是 @synthesize,一个是 @dynamic。如果 @synthesize和 @dynamic都没写,那么默认的就是@syntheszie var = _var;
  2. @synthesize 的语义是如果你没有手动实现 setter 方法和 getter 方法,那么编译器会自动为你加上这两个方法。
  3. @dynamic 告诉编译器:属性的 setter 与 getter 方法由用户自己实现,不自动生成。(当然对于 readonly 的属性只需提供 getter 即可)。假如一个属性被声明为 @dynamic var,然后你没有提供 @setter方法和 @getter 方法,编译的时候没问题,但是当程序运行到 instance.var = someVar,由于缺 setter 方法会导致程序崩溃;或者当运行到 someVar = var 时,由于缺 getter 方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。

在编写一个自定义相册的功能的时候,由于需要继承 UINavigationController写一个ImagePickerViewController,同时ImagePickerViewController又需要和其他的类进行沟通,所以很自然的,ImagePickerViewController类就需要有一个delegate属性,而且需要要求这个属性是一个实现了自定义的ImagePickerViewControllerDelegate协议的属性,那么这个时候问题就来了:父类是已经有一个这样的属性的。直接这么写编译器就会给出一个 warning

Auto property synthesis will not synthesize property 'delegate'; it will be implemented by its superclass, use@dynamic to acknowledge intention

诚然我们可以通过声明一个类似delegateObj的属性来避开这个问题,不过为何编译器会给出这个 warning 却值得研究。

要想研究这个问题首先得从什么是属性开始讲起,在 oc 中属性就是给一个类的成员变量提供封装:

Objective-C properties offer a way to define the information that a class is intended to encapsulate。

通过声明属性,我们可以很简单的为一个成员变量定义其是否是只读的还是读写的,是否是原子操作的等等特性,也就是说如果说封装是为成员变量套了一层壳的话,那么 @property关键字做的事情就是预定义这层壳是个什么样子的壳,然后通过 @sythesize关键字生成真正的壳并把这个壳套在实际的成员变量上(如果没有定义这个成员变量该关键字也可以自动生成对应的成员变量)。当然这层壳包括了自动生成的 get set 方法。
在最开始的时候,我们在代码中写了@property对应的就要写一个@sythesize,在苹果使用了 LLVM 作为编译器以后,如果我们没有写 @sythesize,编译器就会为我们自动的生成一个 @sythesize property = _property。这个特性叫做Auto property synthesize

说了这么多,现在我们来回头看看问题的关键,当我们想覆盖父类的属性并做一些修改的时候,Auto property synthesize这个特性就有点不知道该干嘛了,这个时候他选择不跑出来为我们干活,所以编译器就不会自动生成@sythesize property = _property,但是子类总得有个壳啊,人家都有@property了,怎么办?直接拿过来父类的壳复制一份不管三七二十一套在子类的成员变量身上。注意,有些情况下这会产生运行时的 crash,比如:
一个父类 A

@interface A : NSObject
@property(strong,nonatomic,readonly)NSString *name;

子类 Aa

@interface Aa : A
@property(strong,nonatomic,readwrite)NSString *name;

这种情况下编译器会给出 warning:

Auto property synthesis will not synthesize property 'name' because it is 'readwrite' but it will be synthesized 'readonly' via another property

注意,虽然只给出了 warning,但是这个时候显然 Aa 中是不会自动生成 set 方法的,如果在代码中调用了 Aa 的实例对象的 set 方法,运行时就会 crash,crash 原因是:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Aa setName:]: unrecognized selector sent to instance

所以遇到这个问题怎么解决?在子类中显式的声明一个@synthesize name = _name;就好,这样子类就会如愿的产生他的壳,编译器也不纠结了,就去掉了 warning,从此,天下太平~

object-c 子类覆盖父类属性 详解

// // main.m // test_OC_chind_super_one // // Created by admin on 1/7/16. // Copyright © 2016 je...
  • jeffasd
  • jeffasd
  • 2016年01月07日 13:25
  • 497

OC 中,子类覆盖父类属性 详解

http://segmentfault.com/a/1190000002904657 OC 中,覆盖属性会有怎么样的化学反应? 在编写一个自定义相册的功能的时候,由于需要继承 UINavi...
  • jeffasd
  • jeffasd
  • 2016年01月07日 13:21
  • 6163

OC中类的属性与成员变量的区别

OC中类的属性与成员变量的区别
  • yungeIOS
  • yungeIOS
  • 2017年04月27日 14:28
  • 529

OC 成员变量和属性的区别 .

转自:http://blog.sina.com.cn/s/blog_727bd1560101llwj.html 比如下面这个程序,aboutList,和 otherList 到底有什么不同, ...
  • huang2009303513
  • huang2009303513
  • 2014年08月08日 21:38
  • 20373

OC中的属性特性(Property)

特性(Property) 使用特性我们可以避免手工编写繁琐的setter 和 getter方法,避免因为这些方法来内存的问题,同时也节省编写代码的时间。@property 新的编译器指令,主要功...
  • u014783027
  • u014783027
  • 2014年06月01日 17:05
  • 854

Java中属性的覆盖?

package com.touch.Test; //父类 class FatherClass { public int value; public void getValue(){ ...
  • zcsky027
  • zcsky027
  • 2014年10月26日 22:37
  • 896

Objective-C 中方法的重载,覆盖和隐藏

在C++中,类方法有重载(overload)、覆盖(override)和隐藏(hide)的概念(当然,函数也可重载。)。C++的覆盖和隐藏是个非常容易混淆的概念,尤其隐藏。学到Objective-C,...
  • g5dsk
  • g5dsk
  • 2010年12月24日 03:32
  • 5570

OC中关于属性的一些基本定义

属性介绍: 属性是OC-2.0之后出现的语法,为实例变量提供setter、getter方法的默认实现 属性的出现简化了程序代码量,并且增强了实例变量访问的安全性 属性的属性: 给属性提供了一些...
  • zhangshichi
  • zhangshichi
  • 2015年11月12日 17:24
  • 874

记一次css属性覆盖的问题

问题描述: 某个div有id为signUpModal,其中有个图片我将其初始transform的rotateZ值设置为180deg,这个属性包含在male-picture的class中,因为我是用s...
  • u012062760
  • u012062760
  • 2016年06月09日 11:10
  • 500

OC中@property的所有属性详解

1,assign : 简单赋值,不更改索引计数 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a...
  • xr_rr
  • xr_rr
  • 2014年10月04日 09:46
  • 897
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OC 中,覆盖属性会有怎么样的化学反应?
举报原因:
原因补充:

(最多只允许输入30个字)