objective c - Can NSUUID be extended by inheritance? How? -
objective c - Can NSUUID be extended by inheritance? How? -
hello gents , ladies,
recently (reviewing code) stumbled upon oddity results in bug in our program.
an api using has next implementation (that going write in swift, though original code in objective-c)
class="lang-swift prettyprint-override">internal class myuuid: nsuuid { } which useless returns empty instance.
i going paste code playground here explanation purposes.
for example: creating simple nsuuid this:
let = nsuuid() a.description //this creates valid uuid while creating myuuid should similar
let b = myuuid() b.description //it returns instance, empty. but doesn't work.
inspecting little bit more, reveals nsuuid initialiser creates __nsconcreteuuid instance, while myuuid doesn't , doesn't matter seek do, won't create appropriate uuid.
so, question: possible able create kid implementation of nsuuid?
you utilize class_setsuperclass alter superclass of myuuid @ runtime. approach illegal in swift, due type safety, still in objective-c.
depending on actual goals may able utilize cfuuidref instead.
as requested, here's illustration of class_setsuperclass approach. drop in new single view project.
#import <objc/runtime.h> @interface myuuid : nsuuid - (void) uuidwithhello; @end @implementation myuuid - (void) uuidwithhello { nslog(@"hello! %@", self.uuidstring); } @end @interface viewcontroller () @end @implementation viewcontroller - (void)viewdidload { [super viewdidload]; // additional setup after loading view, typically nib. // create uuid want subclass nsuuid *uuid = [[nsuuid alloc] init]; nslog(@"initial uuid: %@", uuid.uuidstring); // ignore deprecation warnings, since class_setsuperclass deprecated #pragma gcc diagnostic force #pragma gcc diagnostic ignored "-wdeprecated-declarations" // alter myuuid inherit nsuuid's hidden subclass instead of nsuuid class_setsuperclass([myuuid class], [uuid class]); // [uuid class] __nsconcreteuuid // turn deprecation warnings on #pragma gcc diagnostic pop // create new myuuid , print myuuid *myuuid = [[myuuid alloc] init]; [myuuid uuidwithhello]; } @end note bit dangerous. if whatever secret subclass nsuuid has additional instance variables, require more memory, [myuuid alloc] won't request. cause crash later when requests these instance variables.
to around this, instead instantiate myuuid instance this:
nslog(@"initial uuid's class: %@", nsstringfromclass(uuid.class)); class topsecretuuidsubclass = uuid.class; // __nsconcreteuuid myuuid *myuuid2 = [[topsecretuuidsubclass alloc] init]; [myuuid2 uuidwithhello]; object_setclass(myuuid2, [myuuid class]); basically create myuuid2 __nsconcreteuuid , alter myuuid. however, work if myuuid doesn't add together instance variables.
if myuuid does need add together own instance variables, need override +alloc provide additional memory these instance variables, using class_createinstance().
objective-c xcode swift xcode6 nsuuid
Comments
Post a Comment