通过类别覆盖Objective c中的方法 [英] Override a method in Objective c via category

查看:114
本文介绍了通过类别覆盖Objective c中的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下在目标c中起作用:

The following is working in objective c:

// Base Class in ClassA.h and ClassA.m
@interface ClassA : NSObject 
- (NSString *) myMethod;
@end
@implementation ClassA
- (NSString*) myMethod { return @"A"; }
@end

//Category in ClassA+CategoryB.h and ClassA+CategoryB.m
@interface ClassA (CategoryB) 
- (NSString *) myMethod;
@end
@implementation ClassA (CategoryB)
- (NSString*) myMethod { return @"B"; }
@end

问题是,如果我只是导入ClassA.h并发送消息

The question is, if I am just importing ClassA.h and send the message

[myClassA myMethod]; //returns B

为什么返回B?我没有导入ClassA + CategoryB

why is this returning B? I am not importing ClassA+CategoryB

即使是富勒斯,如果我做了以下事情:

Even futhrer, if I did the following:

// Base Class in ClassA.h and ClassA.m
@interface ClassA : NSObject 
- (NSString *) myMethod;
- (NSString *) mySecondMethod;
@end
@implementation ClassA
- (NSString*) myMethod { return @"A"; }
- (NSString *) mySecondMethod { return [self myMethod]; }
@end

//Category in ClassA+CategoryB.h and ClassA+CategoryB.m
@interface ClassA (CategoryB) 
- (NSString *) myMethod;
@end
@implementation ClassA (CategoryB)
- (NSString*) myMethod { return @"B"; }
@end

并调用mySecondMethod:

and call mySecondMethod:

ClassA *a = [[ClassA alloc] init];
NSLog(@"%@",[a myMethod]);

结果仍然是B,尽管没有人知道(由于没有导入)类别实现?!

the result will still be B although nobody knows (due to no import) of the category implementation?!

如果要导入类别,我将只返回B ...

I'd excepted, only to return Bif I was importing the category...

任何提示都值得赞赏.

推荐答案

Objective-C消息传递是动态的,这意味着您是否导入类别都没有关系.该对象将接收消息并执行该方法.

Objective-C messaging is dynamic, this means that it doesn't matter if you import or not the category. The object will receive the message and execute that method.

类别覆盖了您的方法.这意味着,当运行时向该对象发送消息时,无论您导入什么内容,都将始终找到被覆盖的方法.

The category is overriding your method. This means that when the runtime sends a message to that object, will always find the overridden method, no matter what you import.

如果要忽略类别,则不应该对其进行编译,因此可以从编译器源中删除该类别.
另一种方法是子类化.

If you want to ignore a category you shouldn't compile it, so you could remove the category from the compiler sources.
An alternative is subclassing.

也请阅读:

避免类别方法名称冲突

由于在类别中声明的方法已添加到现有类中,因此您在使用方法名称时要非常小心.

Because the methods declared in a category are added to an existing class, you need to be very careful about method names.

如果在一个类别中声明的方法的名称与原始类中的方法的名称相同,或者在同一类(甚至是超类)的另一个类别中的方法的名称相同,则该行为的不确定性取决于哪个方法的实现在运行时使用.如果您在自己的类中使用类别,则不太可能出现问题,但是在使用类别向标准Cocoa或Cocoa Touch类中添加方法时,可能会引起问题.

If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime. This is less likely to be an issue if you’re using categories with your own classes, but can cause problems when using categories to add methods to standard Cocoa or Cocoa Touch classes.

因此,在您的情况下,您没有任何问题,因为如上所述,用户定义的类不太可能发生这种情况.但是您绝对应该使用子类而不是编写类别.

So in your case you haven't got any problem because as stated, this is less likely to happen with user defined classes. But you should definitely use subclassing instead of writing a category.

这篇关于通过类别覆盖Objective c中的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆