0

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.

Nat
  • 12,032
  • 9
  • 56
  • 103

1 Answers1

1

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
nprd
  • 1,942
  • 1
  • 13
  • 16
  • How should i subclass category from AFNetworking? Or do you mean to rewrite AFNetworking? – Nat May 28 '14 at 17:35
  • If you have the source code modify the code to return your own object. Alternatively, you can write a new category with a different signature like `+ (id )YourMethod` and inside this if you need `sharedImageCache` then you can call `[self sharedImageCache]` to get shared cache, manipulate the cache/object within cache and return your own object. – nprd May 28 '14 at 18:30
  • I'm not willing to change source code for it as it may be done without it. With this category I don't think you are right - you don't know which one will be called, so it won't work. – Nat May 28 '14 at 18:44
  • Clearly the method name is different, so your method would be called. What you are trying to achieve with overriding the method? – nprd May 28 '14 at 19:01
  • In this case in each place in AFNetworking I'd still get an instance of sharedImageCache. The problem is that I want to swap sharedImageCache to myImageCache, so every method in that category in AFNetworking will be working on myImageCache not on sharedImageCache. The solution you gave me is working in a opposite way. – Nat May 28 '14 at 19:11
  • Updated answer, try method swizzling? – nprd May 28 '14 at 20:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/54677/discussion-between-naveen-prasad-r-and-vive). – nprd May 28 '14 at 20:53
  • Thank you for the source code, but I know how to swizzle methods. Please reread my question, I was asking how it works with 2 methods from categories - you never know which one loads faster. Unfortunately your answer still doesn't answer my question. – Nat May 29 '14 at 08:20