如何为协议添加属性

如果是协议中的属性,编译器不会自动合成实例变量,相当于只是声明了 setter/getter(注意是声明,没有实现)

第一步,声明协议

1
2
3
@protocol QVNImageProtocol <NSObject>
@property (nonatomic, weak) id<QVNInnerImageLoadDelegate> vn_imageDelegate;
@end

第二步,实现协议的人需要自动合成实例变量

1
2
3
4
5
6
@interface QVNImageView <QVNImageLoadDelegate>
@end

@implementation QVNImageView
@synthesize vn_imageDelegate;
@end

问题来了,自动合成的属性会不会拥有 weak/assign/readonly 等属性呢

实测下来是会的,@synthesize 帮你合成的 setter/getter 会根据协议中 @property 的修饰词来确定

当然你也可以模仿 @synthesize 的作用,手动添加成员变量和 setter/getter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@interface QVNImageView <QVNImageLoadDelegate>
{
__weak id<QVNInnerImageLoadDelegate> _vn_imageDelegate;
}
@end

@implementation QVNImageView
- (id<QVNInnerImageLoadDelegate>)vn_imageDelegate
{
return _vn_imageDelegate;
}

- (void)setVn_imageDelegate:(id<QVNInnerImageLoadDelegate>)vn_imageDelegate
{
if (vn_imageDelegate != _vn_imageDelegate)
{
_vn_imageDelegate = vn_imageDelegate;
}
}
@end

问题:这种情况能否使用 @property 来代替 @synthesize

回答:可以但不建议。因为使用 @property 会有代码重复和歧义,原来协议中定义的修饰符会被你新增的 property 修饰符覆盖,并且后续协议中的属性修改后,这里的代码不会有任何报错