OC 中 覆盖父类属性会有Auto property synthesis will not synthesize property 'xxx'的警告


情景还原


今天无意间弄了一个警告. 警告就会存在着一定的隐藏风险,所以就一定要解决这种异常风险,接下来我们看一下当时的情景代码.

我首先写了一个名为BaseObject的基类 ,基类中具有一个遵循BaseObjectDelegate协议的代理属性对象delegate,如下所示

#import <Foundation/Foundation.h>

@protocol BaseObjectDelegate<NSObject>

- (void)baseObjectDeleagateAction;

@end

@interface BaseObject : NSObject

@property(nonatomic,weak)id <BaseObjectDelegate>delegate;

@end

然后,我写了一个继承于BaseObject的子类 SubObject, SubObject中具有一个遵循SubObjectDelegate协议的代理属性对象delegate,代码如下所示.

#import "BaseObject.h"

@protocol SubObjectDelegate<BaseObjectDelegate,NSObject>

- (void)subObjectDeleagateAction;

@end

@interface SubObject : BaseObject

@property(nonatomic,weak)id <SubObjectDelegate>delegate;

@end

这时候,子类SubObject就会报警告.截图如下所示.

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

这种情况就类似于UIScollView和子类UITableView的关系,两者都还有遵循不同协议的delegate属性,但是并没有警告产生.所以这个警告我们要好好研究一下.


解决方案


我们先说说怎么来解决这个警告,然后我们再来聊一下这个警告是如何产生的以及有什么安全隐患.

首先,我们不会去屏蔽这种警告,那么怎么办呢?最简单的方式就是把子类的delegate 改成别的名称,例如subDelegate,这样子类就会有两个代理属性,一个是继承于父类的,一个是自己定义的.代码如下所示.

@interface SubObject : BaseObject
@property(nonatomic,weak)id <SubObjectDelegate>subDelegate;
@end

还有一种解决方案就是使用@synthesize关键词.我们在.m文件中编写如下代码即可解决警告.

#import "SubObject.h"

@implementation SubObject
@synthesize delegate = _delegate;
@end


警告分析


下面我们就来分析一下警告产生过程以及警告会有什么样的安全隐患.我查阅了网上了很多前人所写的博客,这里只是做了一下记录,并非自己验证过的结果.所以要注意.

要了解这个警告,我们就要了解什么是属性,在OC中属性的定义就是给一个类的成员变量提供了封装,关键字是@property.

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

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

但是好像现在的开发人员对@sythesize的使用频率很低了,那么@sythesize到底有什么作用呢?在最开始的时候,我们在代码中写了@property对应的就要写一个@sythesize,在苹果使用了LLVM (2005年Swift之父Chris Lattner将苹果使用的 GCC 全面转为 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;
@end

子类Aa

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

这种情况下编译器会给出 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,这样问题就解决了.


问题总结


这个问题归根到底是因为Auto property synthesize不工作,导致子类属性直接把父类属性的修饰属性复制到自己身上,这样就会产生安全隐患,最终生成警告. 所以我们要自己写一个显式的声明 @synthesize name = _name; 即可解决问题.

参考原文链接


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容