在Mac上无法通过ARC使用responsToSelector


83

respondsToSelector在ARC环境中致电时,出现以下错误消息Automatic Reference Counting Issue No known instance method for selector respondsToSelector:

这是标题

#import <AppKit/AppKit.h>


@class MTScrollView;

@protocol MTScrollViewDelegate
-(void)scrollViewDidScroll:(MTScrollView *)scrollView;
@end


@interface MTScrollView : NSScrollView 
{

}

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

@end

这是实施文件

#import "MTScrollView.h"

@implementation MTScrollView

@synthesize delegate;


- (void)reflectScrolledClipView:(NSClipView *)aClipView
{
    [super reflectScrolledClipView:aClipView];

    if([delegate respondsToSelector:@selector(scrollViewDidScroll:)])
    {
        [delegate scrollViewDidScroll:self];
    }
}

@end

关于我为什么会收到此错误的任何建议?

Answers:


276

使协议符合NSObject

@protocol MTScrollViewDelegate <NSObject>

否则,编译器不会认为该对象会响应NSObject消息,如respondsToSelector,并会生成警告。它将在运行时成功,而不会出现任何问题。


2
@piobyzrespondsToSelector是的实例方法,NSObject因此系统需要知道该委托是NSObject
David

1
@大卫谢谢,你是对的,另外这里有一些更多的信息:stackoverflow.com/questions/1304176/...
彼得·Byzia

2
@piobyz在ARC之前的“旧世界”中,编译器假定您知道您在做什么,并且在编译时只是忽略了一些东西。现在,ARC为您管理保留和发布。为了确保存在方法,必须在您的项目中找到该方法。使用id时,编译器找不到任何符号。通过将协议限制为NSObject,ARC可以确切地知道任何可能的委托都将包含“ respondsToSelector”。这样可以确保一致性,并且您的内存管理将永远很好。与NSObject不匹配的类如果用作委托将导致错误。
JackPearse 2012年

1
@piobyz:因为它respondsToSelector:是NSObject协议的一部分。该delegate属性声明为id <MTScrollViewDelegate>,它仅表示委托者对该协议中声明的消息进行响应。因此,您需要使该协议符合NSObject协议,以使编译器知道其中respondsToSelector:的其中一个。
彼得·霍西

1
@大卫:不太。delegate没有用类名声明,所以NSObject类在这里不相关-编译器不知道,而且仍然不知道这两个东西是相关的。解决方案的一部分是“ NSObject”,它是NSObject协议,因为它是在此处respondsToSelector:声明的。developer.apple.com/library/mac/documentation/Cocoa/Reference/...
彼得Hosey

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.