繁体   English   中英

离开范围时,Swift在CFRelease中崩溃

[英]Swift crashes in CFRelease when leaving scope

我刚刚投入iOS开发,目前在queryServer函数的结尾处发现函数CFRelease出现运行时错误(我在突出显示的行上添加了注释),但没有错误如果我注释掉对extractIPFromQuery的函数调用。

下面的代码使用服务器的名称,并将IP地址列表返回到该服务器。

func extractIPFromQuery(query: NSArray) -> [String] {
    var addresses = [String]()

    for x in 0...query.count - 1{
        let adr = "\(query[x])"
        let adrStart = adr.startIndex.advancedBy(10)
        let adrEnd = adr.startIndex.advancedBy(18)
        let address = adr.substringWithRange(Range<String.Index>(start: adrStart, end: adrEnd))
        var final = ""

        // Convert the hex version of the address into
        // a human readable version

        for seg in 0...3{
            let start = address.startIndex.advancedBy(seg * 2)
            let end = address.startIndex.advancedBy((seg * 2) + 2)
            let hexRange = Range<String.Index>(start: start, end: end)
            let hexPair = address.substringWithRange(hexRange)

            final += "\(UInt8(strtoul(hexPair, nil, 16)))"
            if(seg != 3){
                final += "."
            }
        }

        addresses.append(final)
    }
    return addresses;
}

func queryServer(hostName: String) -> [String]{
    var ips = [String]()
    if  hostName != "\0" {
        let hostRef = CFHostCreateWithName(kCFAllocatorDefault, hostName).takeRetainedValue()
        while(CFHostStartInfoResolution(hostRef, CFHostInfoType.Addresses, nil) == false){}
        ips += extractIPFromQuery(CFHostGetAddressing(hostRef, nil)!.takeRetainedValue() as NSArray)
    } // Code breaks here
    return ips
}

CFHostGetAddressing中没有“创建”或“复制”,这意味着它不返回(+1)保留的对象。 因此,您必须使用takeUnretainedValue()来获取非托管引用的值。

有关这些命名约定的更多信息,请参见“ Core Foundation内存管理编程指南”中的所有权策略中的“创建规则”和“获取规则”。

您将拥有CFHostGetAddressing返回的数组的CFHostGetAddressing ,这意味着ARC将插入一个release调用以平衡认为需要平衡的retain调用,而实际上并不需要这样做。 您应该使用takeUnretainedValue()代替takeRetainedValue()作为名称的语义CFHostGetAddressing您需要拍摄效果的所有权并不意味着。

从根本takeRetainedValue()takeUnretainedValue()之间的区别在于,前者将指示ARC在变量超出范围时插入release调用,而后者则不会。 从语义上讲,前者告诉您想要或需要拥有该变量的所有权,通常意味着对该对象存在不平衡的retain调用, ARC将对其进行平衡。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM