Arj*_*hta 6 objective-c objective-c-blocks automatic-ref-counting javascriptcore ios7
免责声明:这是一个很长的帖子,但对于那些使用新的ObjectiveC JavascriptCore框架并在ObjC和JS之间进行异步编码的人来说,这可能非常有价值.
大家好,我是Objective C的新手,我正在将一个javascript通信库集成到我的iOS应用程序中.
无论如何,我一直在尝试使用iOS7中引入的新ObjectiveC JavaScriptCore框架.它在很大程度上非常棒,尽管到目前为止记录很差.
混合语言惯例真的很奇怪,但在某些方面也有点解放.
我应该补充一点,我当然正在使用ARC,因此这有助于从Javascript世界中获得很多.但是在ObjectiveC和JSContext callBacks之间移动时,我有一个非常具体的内存使用问题.就像我在Javascript中执行一个函数,然后执行一些异步代码,然后回调到一个定义的ObjectiveC块,然后调用一个定义的JS回调......我只是想确保我做得对(即一些地方没有泄漏记忆)!
只是为了做正确的事情(因为我引用了一个类self来调用ObjectiveC callBacks我创建了一个weakSelf所以它对ARC很好用(从问题中引用:在这个块中强烈捕获self可能会导致保留周期):
__unsafe_unretained typeof(self) weakSelf = self;
Run Code Online (Sandbox Code Playgroud)
现在,说我有一个JSContext并添加一个功能.我希望这个函数接受一个callBack函数并以"Hello"作为参数调用它,并将另一个函数作为callBack传递.即.
// Add a new JSContext.
JSContext context = [[JSContext alloc] initWithVirtualMachine:[[JSVirtualMachine alloc] init]];
// Add a function to the context. This function takes a callBack function and calls it back with "Hello"
[context evaluateScript: @"var functionA = function(callBack){
var aMessage = "Foo";
callBack(aMessage, function(message){
/* message should say: Foo Bar */
});
}" ];
// Note, if you try to copy this code, you will have to get rid of the returns in the JS script.
Run Code Online (Sandbox Code Playgroud)
好的,所以我们有基本的JS方面的东西.现在添加ObjectiveC复杂性.我要添加第一个ObjectiveC CallBack块:
context[@"functionB"] = ^(NSString *theMessage, JSValue *theCallBack){
[weakSelf objCFunction:theMessage withCallBack:theCallBack];
};
Run Code Online (Sandbox Code Playgroud)
在同一个类中,所有这一切都发生在我也有方法定义.这是引起我最关注的地方:
-(void)objCFunction:(NSString *)message withCallBack:(JSValue *)callBack
{
NSString *concatenatedString = [NSString stringWithFormat:@"%@%@", message, @"Bar"];
[callBack callWithArguments:@[concatenatedString]];
}
Run Code Online (Sandbox Code Playgroud)
所以当我打电话时:
[context evaluateScript: @"functionA(functionB);" ];
Run Code Online (Sandbox Code Playgroud)
它应该通过链,它完全符合我的预期.
我主要担心的是,我希望我不会以某种方式捕获沿着这个链条泄漏的JSValue.
帮助我了解ARC/JSMachine如何管理这种在Objective C和Javascript之间流畅调用callBacks的方法的任何帮助都是非常有价值的!
此外,我希望这个问题可以帮助那些正在尝试这个框架的人.
谢谢!
当您有两个对象,每个对象都保留另一个对象的一部分时,就会出现保留循环的问题。它不是特定于 JavascriptCore 的。它甚至不是特定于块的,尽管块使问题更容易陷入困境。
例如
@interface ObjcClass : NSObject
@property (strong,nonatomic) JSValue *badProp;
- (void) makeEvilRetainWithContext:(JSContext *) context;
@end
- (void) makeEvilRetainWithContext:(JSContext *) context{
context[@"aFunc"]=^(JSValue *jsValue){
self.badProp=jsValue;
};
}
Run Code Online (Sandbox Code Playgroud)
nowself.context[@"aFunc"]保留 ObjcClass 对象,因为self.badProp现在位于通过将块分配给 所创建的上下文中的函数 obj 内@"aFunc"。同样,上下文也被保留,因为它自己的强保留值之一被保留在 中self.badProp。
实际上,避免这一切的最好方法就是永远不要尝试将 JSValue 存储在 Objective-C 对象中。似乎确实没有必要这样做,例如
@property (strong,nonatomic) NSString *goodProp;
- (void) makeGoodFunc:(JSContext *) context;
@end
- (void) makeGoodFunc:(JSContext *) context{
context[@"aFunc"]=^(JSValue *jsValue){
self.goodProp=[JSValue toString];
};
}
Run Code Online (Sandbox Code Playgroud)
您的代码不是问题,因为简单地通过方法传递 JSValue(甚至是函数)不会保留它。
另一种思考方式可能是:objCFunction:withCallBack:执行之后,由 表示的对象是否可以self访问作为 传递的 JSValue callBack?如果没有,则没有保留周期。
| 归档时间: |
|
| 查看次数: |
4521 次 |
| 最近记录: |