【问题标题】:How to resolve "no known instance method for selector 'performSelector:withObject:afterDelay:'" when migrating to ARC?迁移到 ARC 时,如何解决“选择器‘performSelector:withObject:afterDelay:’没有已知的实例方法”?
【发布时间】:2012-02-09 07:36:30
【问题描述】:

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:'没有已知的实例方法?

【问题讨论】:

    标签: ios delegates automatic-ref-counting performselector


    【解决方案1】:

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

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

    【讨论】:

    • 这意味着在 ARC 下,我们将代表声明为 id 的日子已经一去不复返了?只是依靠 NSObject 来代替? (对我来说这还是有道理的)
    • ARC 出于内存管理的目的强制执行这些操作。如果您知道您的委托将是 NSObject 类型 - 那么只需说明这一点,这个问题就会消失。
    • 或者仍然使用id,只是不要使用NSObject中的方法。你为什么要使用NSObject 的方法呢?这里有要求吗?
    • 是的,可能需要使用延迟的 performSelector。看到这个问题:stackoverflow.com/q/8844551/221023
    • 你错过了这里的指针:你想要NSObject&lt;OverlayDelegate&gt; *delegate
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

      【讨论】:

      • 注意:在输入我的答案时,出现一条消息,表明答案已由 dtuckernet 发布。所以他的速度更快。
      • 这是因为performSelector:withObject:afterDelay: 是在NSObject 类而不是NSObject 协议上定义的。这就是为什么它出错(在 ARC 下)并且没有出现在代码完成中。
      【解决方案4】:

      我遇到了错误:

      没有已知的选择器类方法conformsToProtocol:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多