On Jan 24, 2009, at 1:19 AM, Antonio Nunes wrote:
I need to be able to force the requested allocation of a cocoa class to always return an instance of my subclass. I have looked into ways of doing that.

First things first....

Why?

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?

This is an inherently fragile path to follow.

I have a solution that seems to work, by using a category on the class to replace the regular invocation, but from the archives I understand that is a Bad Idea that can lead to all manner of unpredictable and hard to trace errors. The current implementation looks like this:

@implementation PDFDocument (PDFDocument_Alloc)

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

@end

This is an excellent demonstration of why category based overrides are rife with danger. The above code is making a boatload of assumptions.

Not the least of which, it assumes that PDFDocument doesn't already override +alloc. If it does, the above breaks it.

The code also assumes that everything that uses PDFDocument is perfectly fine with a subclass of PDFDocument instead. Likely a safe assumption for external-to-the-PDF-framework clients, but maybe not so much for the internal implementation details of the PDF framework itself.

Finally, it assumes that PDFDocument, in and of itself, has nothing within itself that uses, say, -isMemberOfClass: to guide behavior.

There are even more ways that the above might break stuff, but you get the idea.

However, if you do decide to go down this path, you'll want to test across every architecture and bit-width as allocation behavior is one of those things that might optimized at such a specific level.

And you would be counting on the allocation behavior to never change over releases or updates.

As I wrote, this appears to work fine. But if indeed this technique is better avoided, what would be the best alternative? I have looked at class_replaceMethod, but am having difficulties implementing it. What would be the best way to implement a safe alternative to the method listed above?

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

The real question, though, is what are you trying to do?

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