15

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有什么问题?为什么它告诉我“选择器‘performSelector:withObject:afterDelay:’没有已知的实例方法?

4

4 回答 4

16

ARC 并没有造成这种情况——它只是暴露了它。该方法是在 NSObject 上定义的——但 id 不仅仅适用于 NSObject(所以你必须比“id”更具体)。将您的代码更改为:

@interface Overlay : UIImageView {
    NSObject<OverlayDelegate> *delegate;
}

@property (nonatomic, assign) NSObject<OverlayDelegate> *delegate;
于 2012-01-13T01:35:34.367 回答
3

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

于 2012-01-13T01:36:31.403 回答
0

我发现将委托转换为 NSObject* 可以解决问题:

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

由于某些奇怪的原因,自动完成功能甚至没有出现,-performSelector:withObject:afterDelay:所以我不得不手动输入。相反,它只提供-performSelector:-performSelector:withObject:withObject:

我的猜测是,在 Objective-C 中使用 id 作为委托的类型只是愚蠢的,而且我从来不知道为什么包括我自己在内的每个人都这样做,而不是仅仅将其定义为 NSObject。然而,我的协议甚至告诉遵守该协议的人也必须通过这样做来遵守 NSObject 协议:OverlayDelegate <NSObject>- 编译器仍然没有得到它。

所以现在我很满意它和演员阵容一起工作,但感觉就像在吃老鱼。

于 2012-01-13T01:36:28.080 回答
0

我遇到了错误:

没有已知的选择器符合ToProtocol 的类方法:

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

于 2016-08-11T02:02:21.753 回答