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 (Cocoa-dev@lists.apple.com)

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 arch...@mail-archive.com

Reply via email to