[英]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.