Skip to content Skip to sidebar Skip to footer

ObjectiveC And JavaScriptCore: Will Using This Method Of Calling CallBacks Cause Memory Issues?

DISCLAIMER: This is a long post, but could prove very valuable for those grappling with using the new ObjectiveC JavascriptCore framework and doing asynchronous coding between ObjC

Solution 1:

The problem with retain cycles occurs when you have two objects, each of which retains part of another. It's not specific to JavascriptCore. It's not even specific to blocks although blocks make the problem much easier to blunder into.

E.g.

@interface ObjcClass : NSObject
@property (strong,nonatomic) JSValue *badProp;


- (void) makeEvilRetainWithContext:(JSContext *) context;
@end

- (void) makeEvilRetainWithContext:(JSContext *) context{
  context[@"aFunc"]=^(JSValue *jsValue){
    self.badProp=jsValue;
  };
}

The self.context[@"aFunc"] now retains the ObjcClass object because self.badProp is now inside the function obj inside the context created by assigning the block to @"aFunc". Likewise, the context is retained because one of its own strongly retained values is retained in self.badProp.

Really, the best way to avoid all this is just to not try and store JSValue in objective-c objects ever. There really doesn't seem to be a need to do so e.g.

@property (strong,nonatomic) NSString *goodProp;


- (void) makeGoodFunc:(JSContext *) context;
@end

- (void) makeGoodFunc:(JSContext *) context{
  context[@"aFunc"]=^(JSValue *jsValue){
    self.goodProp=[JSValue toString];
  };
}

You code isn't a problem because simply passing a JSValue (even a function) through a method won't retain it.

Another way to think of it might be: After, objCFunction:withCallBack: executes, would there be anyway for the object represented by self to access the JSValue passed as callBack? If not, then no retain cycle.


Solution 2:

Check out the WWDC introduction "Integrating JavaScript into Native Apps" session on Apple's developer network: https://developer.apple.com/wwdc/videos/?id=615 - it contains a section on Blocks and avoiding capturing JSValue and JSContext

In your sample code above, all the JSValues are passed as arguments (the way Apple recommends) so the references only exist whilst the code is executed (no JSValue objects are captured).


Post a Comment for "ObjectiveC And JavaScriptCore: Will Using This Method Of Calling CallBacks Cause Memory Issues?"