Re: Forcing allocation of a subclass
Re: Forcing allocation of a subclass
- Subject: Re: Forcing allocation of a subclass
- From: Jean-Daniel Dupas <email@hidden>
- Date: Sat, 24 Jan 2009 23:19:05 +0100
Le 24 janv. 09 à 22:13, Antonio Nunes a écrit :
Sorry, sent this before I had finished making the necessary changes,
I don't think I need to exchange any implementations if I add the
method with the correct selector (allocWithZone:)
===
On 24 Jan 2009, at 19:20, Bill Bumgarner wrote:
If so, the method_exchangeImplementations() pattern will work. If
not, you'll need to add the method to the class via
class_addMethod().
Let's see if I understand this correctly: you mean I need to add
alloc, or as suggested, allocWithZone: zone to the PDFClerkDocument
class, and after that, I suppose, exchange the method implementations?
No, you don't have to do this if you use exchangeMethod correctly.
You may want to add one to not affect other objects, but it is not
required.
Just in case:
Calling the original implementation in a method you have exchanged is
done using
[self replacedMethodName]
and in a method added at runtime, you have to call
[super originalMethodName]
Make use of Bill's and Jean-Daniel's suggestions I now have:
Method originalMethod = class_getClassMethod([PDFDocument class],
@selector(allocWithZone:));
Method superMethod =
class_getClassMethod(class_getSuperclass([PDFDocument class]),
@selector(allocWithZone:));
if (superMethod == originalMethod) {
// PDF Document does not override allocWithZone:
IMP replacement = class_getMethodImplementation([PDFDocument
class], @selector(replacementAllocWithZone:));
BOOL success = class_addMethod([PDFDocument class],
@selector(allocWithZone:),
replacement,
"@@:@");
}
I verified that the method is added correctly. However, the
replacement method appears not to be called, so I must be doing
something wrong.
From my understanding, the second argument to class_addMethod is the
name the added method will have, so that should be
replacementAllocWithZone, the third argument is the IMP of the
replacement, and the last argument is the array of characters
describing the of the method arguments, resp an object as the return
type, self and cmd and the NSZone object. Is this correct?
Yes it is, but if you don't want to bother with the type string, just
query it using runtime functions:
And you want to add a class method, not an instance method. You have
to add this method to the 'PDFDocument class' meta-class.
Method originalMethod = class_getClassMethod([PDFDocument class],
@selector(allocWithZone:));
Method superMethod =
class_getClassMethod(class_getSuperclass([PDFDocument class]),
@selector(allocWithZone:));
Method replacedMethod = class_getClassMethod([PDFDocument class],
@selector(replacementAllocWithZone:));
if (superMethod == originalMethod) {
class_addMethod(object_getClass([PDFDocument class]),
@selector(allocWithZone:),
method_getImplementation(replacedMethod),
method_getDescription(replacedMethod)->types);
}
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden