【问题标题】:Protocol or class specific selector in objective-cObjective-c 中的协议或类特定选择器
【发布时间】:2015-08-23 11:55:41
【问题描述】:

使用选择器调用存在于多个类中的方法(但在返回或参数类型上具有不同的签名)会导致Multiple methods named [method name] found... 错误。

这已经在其他问题中解决了:

如果重复方法在协议中,则会出现相关问题。对于编译器来说,拥有强类型协议对象仍然是模棱两可的,因为该对象也可能是实现相同签名方法的其他类的实例:

@protocol ExistingMethodProtocol <NSObject>
// This method also exists in UIView, but with a different return type
- (NSString*)contentMode;
@end

@interface ImplementingClass : NSObject <ExistingMethodProtocol>
@end

@implementation ImplementingClass
- (NSString*)contentMode {return nil;}

- (void)problematicCall
{
    // Multiple methods named... error
    [self performSelector:@selector(contentMode)];

    id<ExistingMethodProtocol> idOfProtocol = self;
    // Multiple methods named... error too, even casted
    [idOfProtocol performSelector:@selector(contentMode)];
}
@end

另一种方法是单独创建选择器然后执行,从而绕过编译器检查但导致警告:

SEL selector = @selector(contentMode);
// Warning: PerformSelector may cause a leak because its selector is unknown
[object performSelector:selector];

当协议的方法与相同的签名冲突时,还有哪些其他替代方法可以在这里检查和执行方法?

【问题讨论】:

    标签: objective-c warnings


    【解决方案1】:

    我的 2 美分。使用运行时参考。在这种情况下,它会绕过编译器警告/错误。看起来有几种方法可以做到这一点,这是我的解决方案。

    #import <objc/message.h>
    
    struct objc_method *method = class_getInstanceMethod([self class], @selector(contentMode));
    id answer = method_invoke(self, method);
    

    这应该可以防止选择器在不同协议中命名相同的错误。但我有点不确定在基类和超类中具有不同实现的方法会如何表现。

    【讨论】:

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