RespondsToSelector kann mit ARC auf dem Mac nicht verwendet werden

83

Wenn ich respondsToSelectorin einer ARC-Umgebung anrufe, wird die folgende Fehlermeldung angezeigtAutomatic Reference Counting Issue No known instance method for selector respondsToSelector:

Dies ist der Header

#import <AppKit/AppKit.h>


@class MTScrollView;

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


@interface MTScrollView : NSScrollView 
{

}

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

@end

Dies ist die Implementierungsdatei

#import "MTScrollView.h"

@implementation MTScrollView

@synthesize delegate;


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

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

@end

Irgendwelche Vorschläge, warum ich diesen Fehler erhalte?

David
quelle

Antworten:

276

Passen Sie das Protokoll an NSObject an

@protocol MTScrollViewDelegate <NSObject>

Andernfalls glaubt der Compiler nicht, dass das Objekt auf NSObject-Nachrichten wie reagiert respondsToSelectorund eine Warnung generiert. Es wird zur Laufzeit ohne Probleme erfolgreich sein.

Jason Harwig
quelle
2
@piobyz, respondsToSelectorist eine Instanzmethode von, NSObjectso dass das System wissen muss, dass der Delegat einige der Unterklasse vonNSObject
David
1
@ David danke, du hast recht, zusätzlich hier noch ein paar Infos: stackoverflow.com/questions/1304176/…
Piotr Byzia
2
@piobyz in der "alten Welt" vor ARC hat der Compiler angenommen, dass Sie wissen, was Sie tun, und einige Dinge beim Kompilieren einfach ignoriert. Jetzt verwaltet ARC Retains und Releases für Sie. Um sicherzustellen, dass eine Methode vorhanden ist, muss die Methode in Ihrem Projekt gefunden werden. Während der Arbeit mit id kann der Compiler keine Symbole finden. Durch die Beschränkung des Protokolls auf NSObject weiß ARC genau, dass jeder mögliche Delegat "respondsToSelector" enthält. Dies stellt die Konsistenz sicher und Ihre Speicherverwaltung ist immer in Ordnung. Klassen, die nicht mit NSObject übereinstimmen, verursachen einen Fehler, wenn sie als Delegat verwendet werden.
JackPearse
1
@piobyz: Weil respondsToSelector:Teil des NSObject-Protokolls ist. Die delegateEigenschaft wird als deklariert id <MTScrollViewDelegate>, was nur besagt, dass der Delegat auf in diesem Protokoll deklarierte Nachrichten antwortet. Daher muss dieses Protokoll mit dem NSObject-Protokoll übereinstimmen, damit der Compiler weiß, dass respondsToSelector:es sich um ein Protokoll handelt.
Peter Hosey
1
@ David: Nicht ganz. delegatewird nicht mit einem Klassennamen deklariert, daher ist die NSObject-Klasse hier nicht relevant - der Compiler weiß und weiß immer noch nicht, dass diese beiden Dinge zusammenhängen. Das „NSObject“, das Teil der Lösung ist, ist das NSObject- Protokoll , da dort respondsToSelector:deklariert wird. developer.apple.com/library/mac/documentation/Cocoa/Reference/…
Peter Hosey