In the latest public release of my software, I used method swizzling to force 
creation of my subclass when the system tries to create instances of its 
superclass. However, I have received a very few reports where apparently 
instances of the superclass are still created, and wreak havoc (i.e. they cause 
a crash). In what way is it still possible for instances of the superclass to 
be created?

The swizzling is performed early on during the application startup:

+ (void)initialize
{
        // To force PDFDocuments to be created as NMD_PDFDocuments
        // Necessary because of an issue with PDFThumbnailView
        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(allocWithZoneReplacement:));
        if (superMethod == originalMethod) {
                class_addMethod(object_getClass([PDFDocument class]), 
@selector(allocWithZone:), 
                                                
method_getImplementation(replacedMethod),
                                                
method_getDescription(replacedMethod)->types);
        }

        // To force PDFPages to be created as NMD_PDFPage
        originalMethod = class_getClassMethod([PDFPage class], 
@selector(allocWithZone:));
        superMethod = class_getClassMethod(class_getSuperclass([PDFPage 
class]), @selector(allocWithZone:));
        
        replacedMethod = class_getClassMethod([PDFPage class], 
@selector(allocWithZoneReplacement:));
        if (superMethod == originalMethod) {
                class_addMethod(object_getClass([PDFPage class]), 
@selector(allocWithZone:), 
                                                
method_getImplementation(replacedMethod),
                                                
method_getDescription(replacedMethod)->types);
        }
}


The replacement method lives in a category on PDFPage:

@implementation PDFPage (PDFPage_AllocWithZoneReplacement)

// Forces PDFPages to be created as NMD_PDFPages
+ (id)allocWithZoneReplacement:(NSZone *)zone
{
        if ([self class] == [PDFPage class]) {
                return [NMD_PDFPage allocWithZoneReplacement:zone];
        } else {
                return [super allocWithZone:zone];
        }
}

@end


The only change I can think of that might make a difference is to change:
        if ([self class] == [PDFPage class])
to
        if ([self class] != [NMD_PDFPage class])

but why would this code ever be called for any classes other than either 
PDFPage or NMD_PDFPage? Maybe someone can point out circumstances under which 
this whole setup can fail, or be sidestepped.

-António

----------------------------------------------------
A merry heart does good like medicine
----------------------------------------------------



_______________________________________________

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to