Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.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 Swift在离开范围时在CFRelease中崩溃_Ios_Swift - Fatal编程技术网

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

Ios Swift在离开范围时在CFRelease中崩溃,ios,swift,Ios,Swift,我刚刚投入到iOS开发中,目前在queryServer函数末尾的函数CFRelease中出现了一个运行时错误(我在get突出显示的行上添加了一条注释),如果我注释掉对extractIPFromQuery的函数调用,则不会出现错误 下面的代码获取服务器的名称并将ip地址列表返回给该服务器 func extractIPFromQuery(query: NSArray) -> [String] { var addresses = [String]() for x in 0...

我刚刚投入到iOS开发中,目前在queryServer函数末尾的函数CFRelease中出现了一个运行时错误(我在get突出显示的行上添加了一条注释),如果我注释掉对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
}
func extractIPFromQuery(查询:NSArray)->[String]{
变量地址=[String]()
对于0中的x…query.count-1{
let adr=“\(查询[x])”
设adrStart=adr.startIndex.advancedBy(10)
设adrEnd=adr.startIndex.预付款(18)
let address=adr.substringWithRange(范围(开始:adrStart,结束:adrEnd))
var final=“”
//将地址的十六进制版本转换为
//可读的版本
对于0…3中的seg{
让start=address.startIndex.advancedBy(seg*2)
让end=address.startIndex.advancedBy((seg*2)+2)
设hexRange=Range(开始:开始,结束:结束)
设hexPair=address.substringWithRange(hexRange)
final+=“\(UInt8(strtoul(六角对,零,16))”
如果(分段!=3){
最终+=“”
}
}
地址。追加(最终)
}
返回地址;
}
func queryServer(主机名:String)->[String]{
变量ips=[String]()
如果主机名!=“\0”{
让hostRef=CFHostCreateWithName(kCFAllocatorDefault,主机名)
while(cfhoststartinefolution(hostRef,CFHostInfoType.Addresses,nil)==false){}
ips+=extractIPFromQuery(CFHostGetAddressing(hostRef,nil)!.takeRetainedValue()作为NSArray)
}//代码在此中断
返回IP
}

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

有关这些命名约定的更多信息,请参阅“创建规则”和“获取规则” 在里面
在“Core Foundation的内存管理编程指南”中,

您获得了
CFHostGetAddressing
返回的数组的所有权,这意味着
ARC
将插入一个
release
调用来平衡认为需要平衡的
retain
调用,而实际上它不需要这样做。您应该使用
takeUnrepainedValue()
而不是
takeRetainedValue()
,因为
CFHostGetAddressing
的名称语义并不意味着您需要获得结果的所有权


在基本层面上,
takeRetainedValue()
takeUnrepainedValue()
之间的区别在于前者将指示ARC在变量get超出范围时插入
release
调用,而后者则不会。在语义层面上,前一个表示您想要或需要获得变量的所有权,通常意味着对该对象有一个不平衡的
retain
调用,哪个
ARC
将保持平衡。

在调用
queryServer
时是否传递有效的服务器名称?该代码确实有效,并且ips中填充了一组地址,因为离开
if
范围时会崩溃,这意味着它与作用域中使用的变量之一有关:
hostRef
CFHostGetAddressing
的结果。还可以使用
getnameinfo()
查看一种更简单的方法,将IP地址转换为字符串。谢谢您和@Cristik,它们解决了我的问题。