获取警告设置自定义协议的委托

我在我的一个类中添加了一个自定义协议,当我尝试在prepareForSegue:方法期间设置委托时,我收到编译器警告。 我得到的警告是……

Sending 'MyCustomViewControllerClass *const __strong' to parameter of incompatible type 'id' 

项目构建和运行,一切正常,减去警告。 如果我将添加到我的自定义类,则警告消失。 我错过了什么,或者这是Xcode(6 beta)中的错误? 代码是设置协议/委托的标准代码,但我会发布它…

SomeSecondClass.h

 #import  @class SomeSecondCustomViewController; @protocol SomeSecondCustomViewControllerDelegate  - (void)doThisForMe @end @interface SomeSecondCustomViewController : UIViewController @property (weak, nonatomic) id  delegate; @end 

SomeSecondClass.m

 @interface SomeSecondViewController () …stuff -(void)someMethod { [self.delegate doThisForMe]; } @end 

CustomClass.h

 #import  #import “ SomeSecondViewController.h” @interface MyCustomViewController : UIViewController  //adding on  removes the warning... @end 

CustomClass.h

 ...standard stuff... - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"MySegue"]) { //this is where the warning happens on "self" [segue.destinationViewController setDelegate:self]; } } - (void)doThisForMe { //doing some stuff... } @end 

我已经打开了之前没有警告的项目,现在出现了相同的警告。 我想知道这是否是Xcode问题?

您遇到的问题是Objective-C如何找到匹配的选择器并处理id引用时出现歧义。

UIStoryboardSegue destinationViewController返回一个id 。 然后,您的代码尝试在此id引用上调用setDelegate方法。 由于没有关于此id实际引用的信息,因此它不知道您可能意味着哪个setDelegate:方法(有很多)。 因此,编译器扫描它知道的列表并选择一个。 在这种情况下,它从NSFileManager类中选择了setDelegate:方法。 由于self不符合NSFileManagerDelegate协议,因此会收到警告。

您可以忽略该警告,在这种情况下您的代码将正常工作。

更好的解决方案是通过添加强制转换来帮助编译器:

 [(SomeSecondCustomViewController *)segue.destinationViewController setDelegate:self]; 

这将让编译器知道你真正setDelegate:方法。

顺便说一句 – 将NSFileManagerDelegate添加到您的类中并不是一个有效的解决方案,即使它现在正常工作。 对某些import语句进行简单的重新排序可能会导致编译器做出不同的选择,并且您的警告会返回,但会抱怨不符合其他协议。

事实certificate,这是Xcode 6 beta中的一个错误/变化。 在Xcode 5.1.1上运行这个完全相同的代码不会产生任何警告或错误。 问题是因为在Xcode 6中编译器要求输入类型

 (id) 

为代表。 在Xcode 5.1中,编译器只是期待

 (id) 

代表类型。

正如rmaddy所说,通过铸造类型

 [(SomeSecondCustomViewController *)segue.destinationViewController setDelegate:self]; 

它确实删除了警告,但这应该是一个不必要的步骤,并且会将其归结为Xcode的问题。

尝试显式输入(给类型)destinationVC,如下所示:

 SomeSecondCustomViewController *vc = (SomeSecondCustomViewController *)segue.destinationViewController; vc.delegate = self; 

@rmaddy提供了正确的答案。 对于我们这些在Objective-C方面受过轻微教育的人来说,这是一个更详细的例子。

我改变了我的代码:

  [[segue destinationViewController] setDelegate:self]; UIPopoverController *popoverController = [(UIStoryboardPopoverSegue *)segue popoverController]; self.flipsidePopoverController = popoverController; popoverController.delegate = self; 

至:

  [(UIPopoverController *)segue.destinationViewController setDelegate:self]; UIPopoverController *popoverController = [(UIStoryboardPopoverSegue *)segue popoverController]; self.flipsidePopoverController = popoverController; popoverController.delegate = self; 

并且警告消失了。