【问题标题】:Why does Swift "Managed.fromOpaque.takeUnretainedValue()" retain the value?为什么 Swift "Managed.fromOpaque.takeUnretainedValue()" 保留值?
【发布时间】:2017-01-20 22:26:09
【问题描述】:

我在 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”不会保留该值。

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

【问题讨论】:

  • 是的。我弄清楚了最初的问题。 “passUnretained”不保留,但“takeUnretainedValue”可以。然而这些不是相关的对,但是 passUnretained (+0) 与 passRetained (+1) 对立。你认为我应该删除这个问题,因为没有可能的理由或者不再是编码问题了吗?
  • 我很高兴这对你有意义。不是讽刺。为了正确使用它们并能够审查代码,理解这些术语的含义很重要。

标签: swift unsafe-pointers


【解决方案1】:

其实“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 “Managed.fromOpaque.takeUnretainedValue()” 会保留值?事实是 takeUnretainedValue 不保留,因此造成混乱。
猜你喜欢
  • 1970-01-01
  • 2013-11-17
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2013-01-14
  • 2019-07-07
  • 2022-01-22
  • 2014-02-17
相关资源
最近更新 更多