On Jan 24, 2009, at 9:51 AM, Antonio Nunes wrote:
On 24 Jan 2009, at 18:09, Bill Bumgarner wrote:
Or, more specifically, why do you want to make some bit of framework code which currently allocates an instance of A allocate an instance of SubA instead?

Because of, what I assume to be, a bug in PDFClerkThumbnailView which when one drags multiple pages from or within it, puts the pages in a PDFDocument instead of in the subclass of PDFDocument, which is where the pages live. Dragging a single page works as expected and the page is of the correct subclass. Dragging multiple pages leads to errors. I filed a bug report for this a while back, but I really need a safe workaround until the issue is fixed. (Assuming Apple considers it a bug too. I have never received feedback on it.)

OK -- I would encourage you to be as defensive as possible in your coding of a workaround for this bug.

Check to make sure that the classes and methods are all implemented / not implemented in a way that your code expects.

Ideally, if you can programmatically detect the problematic behavior, do so and verify its presence prior to mucking about with the innards of the PDF* classes.

I would use method_exchangeImplementations(), if absolutely positively necessary. It is about the most innocuous of an otherwise noxious encapsulation breaking implementation pattern.

Thanks. I found that a few hours ago and was able to create the exchange. However, writing a correct replacement method is another thing altogether. The following doesn't work:

Early in application startup:
Method originalMethod = class_getClassMethod([PDFDocument class], @selector(alloc)); Method replacedMethod = class_getClassMethod([PDFDocument class], @selector(allocReplacement));
        method_exchangeImplementations(originalMethod, replacedMethod);

Addition to PDFDocument:
+ (id)allocReplacement
{
        if ([[self class] isEqual:[PDFDocument class]]) {
                        return [ANPDFDocument alloc];
                } else {
                        return [super alloc];
                }
}

I get the impression it replaces alloc for everything, not just for the PDFClerkDocument class. So the app crashes immediately after the implementation exchange. Which doesn't surprise me really. But: Is there a way to make this work using method_exchangeImplementations, or maybe for the particular problem at hand, is there a better way of making the PDFThumbnailView use the correct PDFDocument (sub) class when it deals with multiple selections.

Just to make this clear: I would really rather not create this workaround, but I can't really afford not to let users drag multiple pages in the PDFClerkThumbnailView either.

Ahh... yes -- my suggestion was slightly misleading.

class_getClassMethod() will walk the class hierarchy and return a super's implementation, if the method itself is not found in the subclass.

You'll need to detect whether or not the method already exists in the targeted class. You can use class_copyMethodList() to grab the methods specific to the class and then hunt about within to see if the targeted method is implemented.

If so, the method_exchangeImplementations() pattern will work. If not, you'll need to add the method to the class via class_addMethod().

Normally, when doing this kind of thing, you absolutely positively must call the original implementation of the method -- whether it be in the class or in the superclass -- to ensure that you preserve any existing behaviors.

+alloc, though, is slightly different in that classes typically only override +alloc when they want to do some kind of custom allocation behavior and, by doing so, they would almost never (but not never) call through to super's implementation.

If you are actually replacing +alloc (which, in this case, it seems not), well.... that can be very very tricky.

b.bum


_______________________________________________

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