ios - How do I access the dealloc method in a class category? -
ios - How do I access the dealloc method in a class category? -
i need perform action in dealloc method of category. i've tried swizzling doesn't work (nor great idea).
in case asks, reply no, can't utilize subclass, category.
i want perform action on delay using [nstimer scheduledtimerwithtimeinterval:target:selector:userinfo:repeats:]
or [self performselector:withobject:afterdelay:]
, cancel on dealloc.
the first issue nstimer
retains target, don't want. [self performselector:withobject:afterdelay:]
doesn't retain, need able phone call [nsobject cancelpreviousperformrequestswithtarget:selector:object:]
in dealloc
method or crash.
any suggestions how on category?
i stumbled on solution haven't seen before, , seems work...
i have category that--as 1 does--needs state variables, utilize objc_setassociatedobject
, this:
memento *m = [[[memento alloc] init] autorelease]; objc_setassociatedobject(self, kmementotagkey, m, objc_association_retain_nonatomic);
and, needed know when instances category extending beingness dealloc
ed. in case it's because set observers on self
, , have remove observers @ point, otherwise nskvodeallocatebreak
leak warnings, lead bad stuff.
suddenly dawned on me, since associated objects beingness retain
ed (because of using objc_association_retain_nonatomic
), must beingness release
d also, , hence beingness dealloc
ed...in fact had implemented dealloc
method in simple storage class had created storing state values. and, postulated: my associated objects must dealloced before category's instances are! so, can have associated objects notify owners when realize beingness dealloc
ed! since had retained associated objects, had add together owner
property (which not specified retain
!), set owner, , phone call method on owner in associated object's dealloc
method.
here's modified part of category's .m file, relevant bits:
#import <objc/runtime.h> // can utilize objc_setassociatedobject, etc. #import "targetclass+category.h" @interface targetclass_categorymemento : nsobject { glfloat *_coef; } @property (nonatomic) glfloat *coef; @property (nonatomic, assign) id owner; @end @implementation targetclass_categorymemento -(id)init { if (self=[super init]) { _coef = (glfloat *)malloc(sizeof(glfloat) * 15); } homecoming self; }; -(void)dealloc { free(_coef); if (_owner != nil && [_owner respondstoselector:@selector(associatedobjectreportsdealloc)]) { [_owner associatedobjectreportsdealloc]; } [super dealloc]; } @end @implementation targetclass (category) static nsstring *kmementotagkey = @"targetclass+category_mementotagkey"; -(targetclass_categorymemento *)targetclass_categorygetmemento { targetclass_categorymemento *m = objc_getassociatedobject(self, kmementotagkey); if (m) { homecoming m; } // else m = [[[targetclass_categorymemento alloc] init] autorelease]; m.owner = self; // can allow owner know when dealloc! objc_setassociatedobject(self, kmementotagkey, m, objc_association_retain_nonatomic); homecoming m; } -(void) dostuff { ccsprite_blurablememento *m = [self ccsprite_blurablegetmemento]; // stuff needed category for, , store state values in m } -(void) associatedobjectreportsdealloc { nslog(@"my associated object beingness dealloced!"); // stuff need when category instances dealloced! } @end
the pattern here learned somewhere (probably on s.o.) uses mill method or create memento object. sets owner on memento, , memento's dealloc
method calls allow owner know it's beingness dealloc
ed
caveats:
obviously, have have associated object setobjc_association_retain_nonatomic
, or won't retained , released automatically. this becomes trickier if memento/state associated object gets dealloc
ed under other circumstances owner beingness dealloc
ed...but can train 1 object or other ignore event. the owner
property can't declared retain
, or you'll create strong reference loop , neither object ever qualify dealloc
ed! i don't know it's documented objc_association_retain_nonatomic
associated objects release
d before owner dealloc
ed, seems happen way , must case, intuitively @ least. i don't know if associatedobjectreportsdealloc
called before or after targetclass
's dealloc method--this important! if runs afterwards, if seek access fellow member objects of targetclass
crash! , guess it's afterwards. this little messy, because you're double-linking objects, requires careful maintain references straight. but, doesn't involve swizzling, or other interference runtime--this relies on behavior of runtime. seems handy solution if have associated object. in cases might worth creating 1 grab own dealloc
s!
ios objective-c cocoa-touch memory-management nstimer
Comments
Post a Comment