swift - 为什么 Swift "Managed.fromOpaque.takeUnretainedValue()"保留值?

标签 swift unsafe-pointers

我在 Swift 中用指针做了一些测试,想验证我接受指针的对象没有被保留。

func test1(){
    let str = aaa();
    print(CFGetRetainCount(str))
    let ptr1 = Unmanaged.passUnretained(str).toOpaque()
    print(CFGetRetainCount(str))
    let str2 = Unmanaged<aaa>.fromOpaque(ptr1).takeUnretainedValue();
    print(CFGetRetainCount(str2))
}

结果是 2,2,3。所以“passUnretained”没有保留,但是“takeUnretainedValue”保留了。

更改为“takeRetainedValue”可解决问题,并导致预期的崩溃。输出 2,2,2。

func test1(){
    let str = aaa();
    print(CFGetRetainCount(str))
    let ptr1 = Unmanaged.passUnretained(str).toOpaque()
    print(CFGetRetainCount(str))
    let str2 = Unmanaged<aaa>.fromOpaque(ptr1).takeRetainedValue();
    print(CFGetRetainCount(str2))
}

因此,总而言之,“takeRetainedValue”不保留值。

更新:我编辑了这个问题以删除一些以前令人困惑的陈述并将其返回到一个基本的编程问题。

最佳答案

实际上,“takeUnretainedValue”并没有保留值,而是在返回值后由赋值本身完成的。

我测试发现,只要“passRetained”和“takeRetained”一起使用,“passUnretained”和“takeUnretained”一起使用,那么这个变量就不会泄漏,只是因为新添加的变量+1。

func test1() -> UnsafeMutableRawPointer {
    let str = aaa();
    print(CFGetRetainCount(str))
    let ptr1 = Unmanaged.passRetained(str).toOpaque()
    print(CFGetRetainCount(str))
    let str2 = Unmanaged<aaa>.fromOpaque(ptr1).takeRetainedValue();
    print(CFGetRetainCount(str2))
    print(str2);
    print("111");
    print(str.b)
    return ptr1;
}

let ptr4 = test1();
let str4 = Unmanaged<aaa>.fromOpaque(ptr4).takeUnretainedValue();
print(CFGetRetainCount(str4))
print(str4.b);

这是一个测试,表明 takeUnretainedValue 不会增加引用计数(删除了赋值,但仍然调用了该函数)。

func test1() {
    let str = aaa();
    print(CFGetRetainCount(str))
    let ptr1 = Unmanaged.passUnretained(str).toOpaque()
    print(CFGetRetainCount(str))
    Unmanaged<aaa>.fromOpaque(ptr1).takeUnretainedValue();
    print(CFGetRetainCount(str))
    //print(str2);
    print("111");
    print(str.b)
}

类似的测试表明“takeRetainedValue”会减少保留计数。它指的是来自 passRetained 的“额外保留”,并返回它开始时的值。如果已分配,它也会获得 +1。

关于swift - 为什么 Swift "Managed.fromOpaque.takeUnretainedValue()"保留值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41773350/

相关文章:

macos - 编辑时更改 NSTextField 边框和 BG 颜色

swift3 - 将 NSUUID 转换为 UnsafePointer<UInt8>

c指针递减安全/不安全?

ios - 使用 UnsafeMutablePointer 数组

go - 如何在 Go 中获取指向 Interface{} 的底层值的指针

ios - 如何使用 “Charts” 创建空标签?

swift - Realm 对象服务器。同步初始本地数据库

ios - NSNumberFormatter 0.1 问题

ios - 使用 segues 实现游戏,重新启动时崩溃。 swift