Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
376 views
in Technique[技术] by (71.8m points)

categories - Using Super in an Objective C Category?

I'd like to override a method in an Objective C class that I don't have the source to.

I've looked into it, and it appears that Categories should allow me to do this, but I'd like to use the result of the old method in my new method, using super to get the old methods result.

Whenever I try this though, my method gets called, but "super" is nil... Any idea why? I'm doing iPhone development with the XCode 2.2 SDK. I'm definitely working with an instance of a class, and the method of the class is an instance method.

@implementation SampleClass (filePathResolver)
-(NSString*) fullPathFromRelativePath:(NSString*) relPath
{
    NSString *result = [super fullPathFromRelativePath: relPath];

  ... do some stuff with the old result

    return result;
}

Note and clarification: From what I can see in the Apple Docs, it appears to me that this should be allowed?

Categories docs at developer.apple.com: When a category overrides an inherited method, the method in the category can, as usual, invoke the inherited implementation via a message to super. However, if a category overrides a method that already existed in the category's class, there is no way to invoke the original implementation.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Categories extend the original class, but they don't subclass it, therefore a call to super doesn't find the method.

What you want is called Method Swizzling. But be aware that your code could break something. There's an article on Theocacao written by Scot Stevenson about Method Swizzling in the old Objective-C runtime, Cocoa with Love by Matt Gallagher has an article about Method Swizzling in the new Objective-C 2.0 runtime and a simple replacement for it.

Alternatively, you could subclass the class and then either use the subclass or use + (void)poseAsClass:(Class)aClass to replace the superclass. Apple writes:

A method defined by a posing class can, through a message to super, incorporate the superclass method it overrides.

Be aware that Apple has deprecated poseAsClass: in Mac OS X 10.5.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...