【问题标题】:Objective C: Declaring a selector but implementing it in objects category目标 C:声明一个选择器但在对象类别中实现它
【发布时间】:2023-02-11 02:40:05
【问题描述】:

我在 obj-c 中有一个框架,它包含在其他模块中。我想让将要包含它的模块为某些方法提供自己的实现。

由于序列化这些对象的一些问题,我不能使用子类化。所以,还得靠using类。

我正在考虑为对象声明一个方法/选择器,然后模块将定义类别并实现该方法。像下面这样的东西:

Framework will declare interface like below: 
@interface framework:NSObject
- (void)methodToBeImplemented;
@end

@implementation framework()
- (void)invokeClientDefinedMethod
{
   if([self respondsToSelector:@(methodToBeImplemented)]) {
      [self methodToBeImplemented];
   }
}

//Module-1 will link against this framework and define the category
@implementation framework(methodImplementor)
- (void)methodToBeImplemented 
{
   ...
}
@end

我可以选择完全不在模块本身提供的框架和实现中实现methodToBeImplemented吗? 我知道我可以做到performSelector路线。但我不敢这样做,因为我想发送指向我的方法的指针,这对于 performSelector 来说是不可能的

【问题讨论】:

    标签: ios objective-c objective-c-category


    【解决方案1】:

    如果可能的话,我强烈建议为您的对象使用a delegate pattern,这样调用者就可以传递一个符合协议的委托,而不是直接扩展类。这是实现这种系统的正常方式。但是如果有一个特殊的原因委托是不可能的,你可以构建你所描述的。

    您正在寻找的是 informal protocol,这是在引入 @optional 之前几乎所有协议的处理方式。

    您要做的是在您的公共标头中为您的班级定义一个类别:

    @interface Framework (OverridePoints)
    - (void)methodToBeImplemented
    @end
    

    这声明可能存在这样的方法,但它并不强制执行它的实际实现。关键是在括号中有一个名字。这可以是任何东西(我在这里使用“OverridePoints”),但它不能为空,因为那将是一个扩展而不是一个类别。

    一旦你有了它,那么你的其他想法就会起作用。您可以测试respondsToSelector:,消费者可以按照您的描述实施(或不实施)类别方法。

    一个危险是没有什么可以阻止程序的多个部分在类别中实现相同的方法。这是未定义的行为,但编译器不会为您捕获它。

    【讨论】:

      猜你喜欢
      • 2010-12-10
      • 2013-07-06
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      • 2023-02-04
      • 2011-08-23
      • 2020-09-29
      • 1970-01-01
      相关资源
      最近更新 更多