Re: Forcing subclass creation through method swizzling not airtight?
Re: Forcing subclass creation through method swizzling not airtight?
- Subject: Re: Forcing subclass creation through method swizzling not airtight?
- From: Jean-Daniel Dupas <email@hidden>
- Date: Sun, 11 Mar 2012 10:48:43 +0100
Yes.
+initialize is not call until you try to use your class.
So there is no garantee it will be call at all, and even if it is called, nothing prevent creation of instance of the super class before it append.
Le 11 mars 2012 à 08:05, Antonio Nunes a écrit :
> 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 (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
-- Jean-Daniel
_______________________________________________
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