Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSMapTable中的迭代键将永远保留弱值_Ios_Swift - Fatal编程技术网

Ios NSMapTable中的迭代键将永远保留弱值

Ios NSMapTable中的迭代键将永远保留弱值,ios,swift,Ios,Swift,我试图使用NSMapTable来弱存储一些对象实例,这些实例由字符串索引 (我的用例是存储一些有关远程服务器的缓存元数据,并让每个活动客户端共享该元数据。当不再有客户端连接到该特定服务器时,应将元数据从内存中删除。) 这一切都很好,只要我从未迭代过键。看起来,如果我迭代了一个特定的键,该键的值将永远不会被释放 我已设法将其简化为一个小代码段,以显示问题: import Foundation class Foobar { let id: String init(_ id: Str

我试图使用
NSMapTable
来弱存储一些对象实例,这些实例由字符串索引

(我的用例是存储一些有关远程服务器的缓存元数据,并让每个活动客户端共享该元数据。当不再有客户端连接到该特定服务器时,应将元数据从内存中删除。)

这一切都很好,只要我从未迭代过键。看起来,如果我迭代了一个特定的键,该键的值将永远不会被释放

我已设法将其简化为一个小代码段,以显示问题:

import Foundation

class Foobar {
    let id: String
    init(_ id: String) { print("init \(id)"); self.id = id }
    deinit { print("deinit \(id)") }
}

let map = NSMapTable<NSString, Foobar>(keyOptions: .strongMemory, valueOptions: .weakMemory)

func addSome() {
    let a = Foobar("a")
    let b = Foobar("b")
    let c = Foobar("c")

    map.setObject(a, forKey: "a")
    map.setObject(b, forKey: "b")
    map.setObject(c, forKey: "c")

    let e = map.keyEnumerator()
    print("nextObject: \(e.nextObject() ?? "nil")")
    print("nextObject: \(e.nextObject() ?? "nil")")
    print("nextObject: \(e.nextObject() ?? "nil")")
    print("nextObject: \(e.nextObject() ?? "nil")")
}

addSome()

print(map.object(forKey: "a") ?? "nil")
print(map.object(forKey: "b") ?? "nil")
print(map.object(forKey: "c") ?? "nil")
<代码>导入基础 福巴级{ let id:String init(id:String){print(“init\(id)”;self.id=id} deinit{print(“deinit\(id)”)} } let map=NSMapTable(键选项:.strong内存,值选项:.weakMemory) func addSome(){ 设a=Foobar(“a”) 设b=Foobar(“b”) 设c=Foobar(“c”) map.setObject(a,forKey:“a”) map.setObject(b,forKey:“b”) map.setObject(c,forKey:“c”) 设e=map.keyEnumerator() 打印(“nextObject:\(e.nextObject()??“nil”)) 打印(“nextObject:\(e.nextObject()??“nil”)) 打印(“nextObject:\(e.nextObject()??“nil”)) 打印(“nextObject:\(e.nextObject()??“nil”)) } addSome() 打印(映射对象(forKey:“a”)??“nil”) 打印(映射对象(forKey:“b”)??“nil”) 打印(映射对象(forKey:“c”)??“nil”) 如果我注释掉一个或多个
e.nextObject()
调用,相应键的值将被正确释放,
map.object(forKey:)
将正确返回
nil


在我以某种方式使用完枚举器之后,是否必须手动清理它?

显然,映射枚举器返回“autorelease”对象–这些对象在当前autorelease池的作用域离开时释放

在iOS或macOS应用程序中,当程序控制返回到主事件循环时会自动发生。在任何情况下,您都可以使用本地

在枚举后立即释放对象

备注:
nsemulator
是一个
序列
,因此您可以使用for循环枚举它:

autoreleasepool {
    let e = map.keyEnumerator()
    for case let key as String in e {
        print(key)
    }
}
autoreleasepool {
    let e = map.keyEnumerator()
    for case let key as String in e {
        print(key)
    }
}