This is really cool...so I can replace a method without being a subclass or
category.
So I implemented an NSObject subclass with the new method, and did the method
exchange, and my new method was called instead of the old one, but I had a
problem - the call to the switched out method (dealloc from the
NSConcreteNotification) didn't work. I assumed that was because the old
implementation of dealloc was now moved to my class, so I changed the method
switching so that it ensures that the old dealloc is replaced with the
implementation of mydealloc, and that I have added a method to the
NSConcreteNotification which is called mydealloc, and does the things that the
old dealloc did.
This seems to work, so I thought I'd post it here in case anyone else needs to
replace a method in a private class, and be able to call the original
implementation.
#import <objc/runtime.h>
#import <Cocoa/Cocoa.h>
@interface MyConcreteNotification : NSObject {
}
- (void)mydealloc;
@end
@implementation MyConcreteNotification
+ (void)load {
Method originalMethod =
class_getInstanceMethod(NSClassFromString(@"NSConcreteNotification"),
@selector(dealloc));
Method replacedMethod = class_getInstanceMethod(self,
@selector(mydealloc));
IMP imp1 = method_getImplementation(originalMethod);
IMP imp2 = method_getImplementation(replacedMethod);
// Set the implementation of dealloc to mydealloc
method_setImplementation(originalMethod, imp2);
// Add a mydealloc method to the NSConcreteNotification with the
implementation as per the old dealloc method
class_addMethod(NSClassFromString(@"NSConcreteNotification"),
@selector(mydealloc), imp1, NULL);
}
- (void)mydealloc {
NSLog(@"My concrete notification is being deallocated");
NSLog(@"Name: %...@\nobject: %...@\nuser Info: %...@\n", [self name],
[self object], [self userInfo]);
// Call the original method, whose implementation was exchanged with
our own.
// Note: this ISN'T a recursive call, because this method should have
been called through dealloc.
NSParameterAssert(_cmd == @selector(dealloc));
[self mydealloc];
}
@end
Regards.
Gideon
>
> On iPhone and 64-bit Mac, the linker enforces internal classes more strictly.
> NSConcreteNotification is private, so you can't link to it or subclass it.
> You can still get the class via runtime introspection like
> NSClassFromString(), which for debugging purposes ought to be good enough.
> --
> Greg Parker [email protected] Runtime Wrangler
_______________________________________________
Cocoa-dev mailing list ([email protected])
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]