传递给 JavaScriptCore 后 NSObject 未被释放

NSObject not being released after passing to JavaScriptCore

我正在创建一个 JSContext 并评估一个简单的 javascript...

function test(obj) {
}

接下来,我正在创建一个 NSObject,其中只包含一个 INITDEINIT 函数。

当我调用 javascript 测试函数并传入 NSObject 时,NSObjects DEINIT 方法永远不会被调用。我不确定为什么在测试函数执行后没有任何东西应该让它保持活动时它没有被释放。

Swift游乐场

import UIKit
import JavaScriptCore

/**************************/
/******* SwiftObject ******/
/**************************/
@objc protocol SwiftObjectExport: JSExport {
}

class SwiftObject: NSObject, SwiftObjectExport {
    override init() {
        super.init()
        print("[INIT] SwiftObject")
    }

    deinit {
        print("[DEINIT] SwiftObject")
    }
}

/**************************/
/******** Main ************/
/**************************/

// DEINIT does NOT fires with this test
func test() {
    let jsContext = JSContext()
    jsContext?.evaluateScript("function test(obj) { } ")

    let obj = SwiftObject()
    jsContext?.objectForKeyedSubscript("test").call(withArguments: [obj])
}

// DEINIT fires with this test
func test2() {
    let jsContext = JSContext()
    jsContext?.evaluateScript("function test(obj) { } ")

    let obj = SwiftObject()
}


print("Running test 1...")
test() // DEINIT does NOT fires with this test

print("Running test 2...")
test2() // DEINIT fires with this test

在实际应用中,您的所有代码都包装在一个自动释放池中。在操场上,情况并非如此。

只需在您的测试代码周围添加一个自动释放池,即可解决您的问题:

autoreleasepool {
    print("Running test 1...")
    test()

    print("Running test 2...")
    test2()

    print("Inside autorelease pool")
}

print("Outside autorelease pool")

输出:

Running test 1...
[INIT] SwiftObject
Running test 2...
[INIT] SwiftObject
[DEINIT] SwiftObject
Inside autorelease pool
[DEINIT] SwiftObject
Outside autorelease pool