如何解决“没有已知的select器实例方法performSelector:withObject:afterDelay:'”当迁移到ARC?

ARC迁移工具在开始迁移之前拒绝接受此代码:

[self.delegate performSelector:@selector(overlayDismissed:) withObject:self afterDelay:0]; 

委托人被强制使用协议来实现这个方法,它应该可以正常工作:

 @protocol OverlayDelegate <NSObject> - (void)overlayDismissed:(Overlay*)overlay; @end @interface Overlay : UIImageView { id<OverlayDelegate> delegate; } @property (nonatomic, assign) id<OverlayDelegate> delegate; 

ARC有什么问题? 为什么它告诉我有没有已知的实例方法select器performSelector:withObject:afterDelay:'?

ARC并没有造成这种情况 – 这只是揭露它。 这个方法是在NSObject上定义的 – 但是id的作用不仅仅是NSObject(所以你必须比'id'更具体)。 将您的代码更改为:

 @interface Overlay : UIImageView { NSObject<OverlayDelegate> *delegate; } @property (nonatomic, assign) NSObject<OverlayDelegate> *delegate; 

很简单,你的对象是idtypes的,并且符合NSObject协议。 然而,这个协议并没有声明performSelector:withObject:afterDelay: ,所以ARC不知道这个方法正在做什么以及它是否保留了任何东西。 使用NSObject或在进行方法调用之前进行强制转换。

我想通过将委托转换为NSObject *解决了这个问题:

 [self.delegate performSelector:@selector(overlayDismissed:) withObject:self afterDelay:0]; 

对于一些奇怪的原因autocompletion甚至没有拿出-performSelector:withObject:afterDelay:所以我不得不手动键入它。 相反,它只提供了-performSelector:-performSelector:withObject:withObject:

我的猜测是在Objective-C中使用id作为代表的types是愚蠢的,我从来不知道为什么包括我自己在内的每个人都这样做,而不是把它定义为NSObject。 然而,我的协议甚至告诉任何符合该协议的人也必须遵守NSObject协议: OverlayDelegate <NSObject> – 但编译器仍然没有得到它。

所以现在我很满意它与演员合作,但感觉就像吃了老鱼。

我遇到错误:

select器conformsToProtocol没有已知的类方法:

原因是:文件名不等于@interface@implementation的类名。