Xcode错误:没有已知的选择器实例方法

时间:2011-12-05 15:30:48

标签: objective-c xcode

我需要帮助调试我的课程。我收到一个如此奇怪的错误,以至于我找不到任何类似的错误,所以我只是放下我的大部分代码。

//Tab.h
#import <UIKit/UIKit.h>
@class Tab;
@protocol TabDelegateDataSource <NSObject>
@required
-(void)removeTab:(Tab *)tab;
@end

@interface Tab : UIView
{
     id <TabDelegateDataSource> __strong _delegate;
}

@property(strong) id <TabDelegateDataSource> delegate;

-(void)removeTab;

@end

//  Tab.m
#import "Tab.h"
@implementation Tab
@synthesize delegate = _delegate;
-(void)removeTab
{
    [self.delegate removeTab:self];//Error here saying: No known instance method for selector 'removeTab:'  
}

@end

9 个答案:

答案 0 :(得分:15)

我现在可以随意重新创建并修复此错误。

确保.h标头定义了这个...

@protocol TabDelegateDataSource <NSObject>
-(void)removeTab:(Tab *)tab;
@end

... 包括,无论您打算在何处使用该委托,例如位于.m源代码顶部的某处,包括:

[self.delegate removeTab:self]

如果编译器只看到TabDelegateDataSource的前向定义,请执行以下操作:

@protocol TabDelegateDataSource;

你会收到错误:

error: no known instance method for selector 'removeTab:'

而不是预期的前向定义相关错误

答案 1 :(得分:6)

我认为这对Xcode来说是一个愚蠢的问题我重新启动了应用程序几次并最终解决了问题。

答案 2 :(得分:4)

在调用方法之前,您应该始终以这种方式检查您的委托,即使使用所需的协议方法:

if( self.delegate != nil && [ self.delegate respondsToSelector: @selector( removeTab: ) ]
{
    /* Call delegate method... */
}

即使对于所需方法,这样做也会增加额外的安全性,因为此检查是在运行时进行的 有人可能会忽略或禁用编译器警告,或者使用类型转换来欺骗编译器。

例如:

UILabel * label        = [ [ UILabel alloc ] initWithFrame: CGRectZero ];
someTableView.delegate = ( id < UITableViewDelegate > )label;

此外,您可能希望将performSelector用于实际的方法调用:

[ self.delegate performSelector: @selector( removeTab: ) withObject: self ];

答案 3 :(得分:2)

确保您没有在界面中错误地声明委托属性(可能是通过从另一个文件复制和粘贴)。例如:

@protocol SomeDelegate

...

@end

@interface SomeClass

...

@property (nonatomic, retain) id<DifferentDelegate>delegate; 


@end

由于与indtended协议不匹配,上面的行将导致“没有已知的选择器实例方法...”,可能是复制和粘贴错误。此外,它可能会覆盖它实际所属的不同类的正确引用,远离这行代码,使其难以发现。

纠正上述声明您的财产的预期协议:

@property (nonatomic, retain) id<SomeDelegate>delegate;

答案 4 :(得分:1)

尝试将delegate重命名为delegateForTab之类的其他人。

您的班级TabUIView的子类,因此self.delegate的{​​{1}}类也是self的子类。 UIView可能有自己的委托(它继承自UIResponder,并且来自NSObject),并且它没有UIView方法。只是我的个人猜测 我的解决方案是重命名它(找不到它是否也可以被子类化的答案)。

建议使用委托:您应该实现-(void)removeTab并在其他视图控制器中使用protocol,而不是在您声明它的同一个类中。 :)

答案 5 :(得分:1)

有人可能需要,

SEL selector = NSSelectorFromString(@"removeTab");

if([self.delegate respondsToSelector:selector]) {
    objc_msgSend(self.delegate, selector);
}

注意:不要忘记这一点,#import <objc/message.h>

答案 6 :(得分:1)

我的问题是我错过了在协议中声明<NSObject>

@protocol CustomProtocol <NSObject>
- (void)doSomethingWithSize:(CGSize)size;
@end

答案 7 :(得分:0)

此错误不是编译器错误,不是吗?因为我的代码没有编译器错误。

因此,如果这是运行时错误,您是否在委托类中声明了<TabDelegateDataSource>,如下所示:

@interface SomeClass : UIView <TabDelegateDataSource>

如果您这样做,编译器应该警告您是否找不到您的实例方法。

或许您也应该发布代理类的代码以获取更多信息。

P.S。代表不应该是__strong。您最好使用__unsafe_unretained

答案 8 :(得分:0)

我导入appdelegate.h并解决了错误...