【问题标题】:Objective-C Category [duplicate]Objective-C 类别 [重复]
【发布时间】:2012-10-28 16:26:42
【问题描述】:

可能重复:
What happens if two ObjC categories override the same method?

我在 NSString 类上有两个类别,如下所示:

//第一类

#import "NSString+MyCategory1.h"

@implementation NSString (MyCategory1)

-(void)myMethod{
    NSLog(@"this is my method from category 1");
}

@end

//第二类

#import "NSString+MyCategory2.h"

@implementation NSString (MyCategory2)

-(void)myMethod{
    NSLog(@"this is my method from category 2");
}

@end

但以下主要方法总是从MyCategory1 调用myMethod,即使在相同的导入已被注释掉之后。

#import <Foundation/Foundation.h>
//#import "NSString+MyCategory1.h"
#import "NSString+MyCategory2.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        [[[NSString alloc]init] myMethod];

    }
    return 0;
}

请任何人解释这种行为以及这种行为在实践中的用途。

【问题讨论】:

  • 你为什么用同样的方式命名这两种方法?

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


【解决方案1】:

我认为这表明您不应该在有冲突的类别中使用方法。

我的(半知情的)猜测是,哪个方法被调用到应用程序的编译方式,所以它不是你可以在运行时影响的东西。而且它在实践中并没有真正的用处,它只是……发生了什么。

至于为什么会发生这种情况,头文件并没有说明调用该方法时要做什么,只是存在它的实现。在你的情况下,它确实存在。它只是碰巧不是你想要的。

【讨论】:

  • 虽然我真的不知道编译器/链接器中发生了什么,但效果对我来说似乎是一个错误。我的直觉反应是,如果无法区分方法名称,它应该在链接时导致重复符号错误,而不是在执行期间任意选择。
  • @PhillipMills 不,这不是错误。这就是类别的工作方式。当一个类别被加载时,它会添加它实现的方法,或者如果它们已经存在则覆盖它们。这是故意发生的,并且没有重复的符号错误,因为它们是不同的符号,因为它们属于不同的类别。这不是执行期间的任意选择 - 要加载的最终类别获胜。
  • 感谢您提供的信息...尽管除非有办法控制加载顺序(?),否则从开发人员的角度来看,我仍然会称其为任意效果。 :)
  • 按照设计工作并不一定意味着设计很好......
  • 类别不能替代子类。如果我想让一个类对同一条消息做出不同的反应,我必须对其进行子类化并覆盖该消息。如果我们允许使用相同的方法加载多个类别,可能会导致代码无法维护。
猜你喜欢
  • 2013-02-25
  • 1970-01-01
  • 2011-05-10
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多