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

时间:2014-06-16 17:13:17

标签: ios objective-c xcode xcode6

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

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

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

SomeSecondClass.h

#import <UIKit/UIKit>

@class SomeSecondCustomViewController;

@protocol SomeSecondCustomViewControllerDelegate <NSObject>
- (void)doThisForMe
@end

@interface SomeSecondCustomViewController : UIViewController

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

@end

SomeSecondClass.m

@interface SomeSecondViewController ()
…stuff

-(void)someMethod {

    [self.delegate doThisForMe];
}

@end

CustomClass.h

#import <UIKit/UIKit.h>
#import “ SomeSecondViewController.h”

@interface MyCustomViewController : UIViewController <SomeSecondCustomViewControllerDelegate>
//adding on <NSFileManagerDelegate> 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问题?

4 个答案:

答案 0 :(得分:12)

您遇到的问题是Objective-C找到匹配的选择器并处理id引用的模糊性。

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

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

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

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

这将让编译器知道您真正想要的setDelegate:方法。

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

答案 1 :(得分:1)

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

(id<NSFileManager>)

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

(id)

代表类型。

正如rmaddy所说,通过在

中输入类型
[(SomeSecondCustomViewController *)segue.destinationViewController setDelegate:self];

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

@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;

警告消失了。