如果一个类支持包含具有相同名称的属性的协议会发生什么?

时间:2013-07-03 07:12:15

标签: objective-c xcode4.5

这是我的班级

@interface BGImageBookController () <BGPageViewControllerDelegateProtocol>
@property (strong, nonatomic) IBOutlet UIPageViewController *pvc;

它包含一个名为pvc的属性。 pvc不是只读属性。

然而,BGImageBookController也支持协议

@protocol BGPageViewControllerDelegateProtocol <NSObject>

@property (readonly,nonatomic) UIPageViewController * pvc;
-(void)reDrawEverything;
@end

在协议中,pvc是只读属性。这是因为PageViewControllerDelegate不需要更改pvc。

这会导致冲突。

我得到了: /business/Dropbox/badgers/BadgerNew/BGImageBookController.m:30:17:自动合成时的Readonly IBOutlet属性可能无法与'nib'加载器一起正常工作

我尝试通过添加

来解决这个问题
@dynamic pvc;

然后我得到了这个运行时错误

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<BGImageBookController 0x1e0df340> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key pvc.'
*** First throw call stack:
(0x3120e2a3 0x38eb397f 0x3120df99 0x31a7b1d9 0x31a76f2b 0x3119461b 0x331b331d 0x331b2b9b 0x330ab03d 0x3303546d 0x14b7c9 0x14b8fd 0x14b9b1 0xc8eeb 0xc705f 0xc71a7 0x33133d89 0x330fb3f5 0x332e8a39 0x3301f82f 0x3301e293 0x330291e7 0x33028db3 0x33016801 0x3301611b 0x34d195a3 0x34d191d3 0x311e3173 0x311e3117 0x311e1f99 0x31154ebd 0x31154d49 0x34d182eb 0x3306a301 0x37299 0x37220)
libc++abi.dylib: terminate called throwing an exception

所以基本上BGImageBookController以两种方式支持属性pvc。

它有一个名为pvc的IBOutlet属性 它支持一种需要只读属性pvc。

的协议

我认为一切都应该正常。毕竟,拥有非只读属性意味着还支持-(UIPageViewController *) pvc;

当然我可以在协议中更改变量名,并在我的类中重新实现

-(UIPageViewController *)   pvc1
{
    return self.pvc;
}

但我认为即使不这样做,我也应该能够做到这一点。毕竟,班级已经支持

-(UIPageViewController *)   pvc

即它是一个名为pvc的属性,其类型为UIPageViewController

2 个答案:

答案 0 :(得分:2)

似乎只有编译器对pvc的两个声明感到困惑 财产并发出警告。

您的代码运行没有问题,您不必添加@dynamic@synthesize语句。

您可以使用

取消执行块中的警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreadonly-iboutlet-property"
@implementation BGImageBookController
#pragma clang diagnostic pop

请注意,仅当您在类扩展中声明插座时才会显示警告。 如果您将插座声明移动到“BGImageBookController.h”中的公共接口, 警告也消失了。

这看起来像编译器错误,您可以在bugreporter.apple.com上提交错误。

答案 1 :(得分:1)

将您的财产定义为:

@property (readwrite, strong, nonatomic) IBOutlet UIPageViewController *pvc;

完全合成它:

@synthesize pvc = _pvc;

目前你告诉编译器其他人将合成访问器方法,但事实并非如此,因此在运行时你最终会尝试调​​用一个不存在的方法。