I use a specific API, which has some class, for example ClassA
.
ClassA
has a property importantProperty
, ivar = _importantProperty
, setter = setImportantProperty
What I need is actually to handle in debug when is property is changed, and what values are set to this property and print the stacktrace.
I can not inherit this class and override this method in my case, because it has defined class.
So I created a debug category, which overrides setImportantProperty
method and now I can handle the stacktrace and values changes, but this method makes original method unreachable, and ivar value can not be changed. Is there any way to change this ivar?
Here is my method:
@implementation ClassA (Test)
-(void) setImportantProperty:(id) newValue {
NSLog(@"%@, %@", newValue, [NSThread callStackSymbols]);
}
@end
So the question is there any way to implement such code _importantProperty = newValue
in my method or are there any other ways to use in my case?
Thanks in advance!
As @vikingosegundo suggested, you could use method swizzling:
Here we declare a new method
swizzled_setImportantProperty:
, and at runtime we swap it's implementation withsetImportantProperty:
implementation. So that when we callsetImportantProperty:
in code, the implementation forswizzled_setImportantProperty
will be called and vice versa.That's why when we call
swizzled_setImportantProperty:
inside theswizzled_setImportantProperty:
implementation, it won't call an endless recursion, becausesetImportantProperty:
implementation will be called. Just what we need.UPDATE: Since overriding a
+load
method might cause problems if it have already been implemented (or if might be implemented in the future by the library creators), there is a better option suggested by @JoshCaswell :