Nat
Nat

Reputation: 12948

How should CategoryA override categoryB method

In AFNetworking 2.0, in UIImageView+AFNetworking there is a method:

+ (id <AFImageCache>)sharedImageCache

I want to override it and return here my custom object. I'd like also to override all the methods in AFImageCache, so basically I'd make a new protocol here. I've thought about method swizzling, however because lack of experience I'm not sure if it works ok with 2 categories. What if my category loads before AFNetworking category, will it still be working?

At all, is this approach a good one? I want to add disc caching to the memory one and I wonder which way is the cleanest one in terms of code quality.

Upvotes: 0

Views: 85

Answers (1)

nprd
nprd

Reputation: 1942

Do not use Categories to override a method. Per the documentation

"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. "

refer to the documentation at "Avoid Category Method Name Clashes" --> https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/ProgrammingWithObjectiveC.pdf

Subclass and override the method instead and use the subclass?

Analyzing your scenario, It make sense to do method swizzling. Note: Make sure yourCache will behave the same way as sharedImageCache, else it will result in crash.

@implementation UIImageView (Swizzling)

      + (void)load {

                static dispatch_once_t token;
                dispatch_once(&token, ^{

                    Class myClass = [self class];

                    Method originalMethod = class_getInstanceMethod(myClass, @selector(sharedImageCache));
                    Method newMethod = class_getInstanceMethod(myClass, @selector(NewSharedImageCache:));
                    method_exchangeImplementations(originalMethod, newMethod);
                });
            }

            //This is just for sample. you can create your buffer in your own way
            static id <yourCache> yourBuffer;
            + (id <yourCache>)NewSharedImageCache
            {
                return yourBuffer;
            }

@end

Upvotes: 1

Related Questions