NSData导致泄漏

时间:2016-02-29 17:23:33

标签: ios swift swift2 nsdata

我有一个C char *cArray并且它的长度,我需要将其转换为NSData 我这样做了:

var data: NSData? = NSData(bytesNoCopy: cArray, length: Int(length))

它正在发挥作用。问题是这会导致一些内存泄漏。我不知道为什么,但我可以在分配工具上看到它是malloc 64字节,并且在函数完成或我将其设置为null时不释放它。

这个代码被大量调用,所以我需要它无泄漏。我该怎么做才能防止泄漏?

编辑:这是代码

func on_data_recv_fn(buf: UnsafeMutablePointer<CChar>, length: CInt, user_data: UnsafeMutablePointer<Void>) -> CInt {
    guard buf != nil else {
        NSLog("on_data_recv_fn buf is nil")
        return -1
    }

    //var data: NSData? = NSData(bytesNoCopy: buf, length: Int(length), freeWhenDone: true)
    var data: NSData? = NSData(bytesNoCopy: buf, length: Int(length))
    let succeededWriting = Int(PacketTunnelProvider.sendPackets(data!))
    data = nil
    return CInt(succeededWriting)
}

根据记忆仪器,这里有泄漏。 sendPackets函数不保存数据,因此不存在问题。

编辑:附加乐器的图像。 instruments image

2 个答案:

答案 0 :(得分:2)

嗯,似乎如果我使用autoreleasepool,由于某些原因,一切都可以。

答案 1 :(得分:1)

Objective-C支持的类型的内存管理是一个庞大而有趣的话题。例如,见:

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html

您可能还会发现此问题很有用:

Is it necessary to use autoreleasepool in a Swift program?

另外,我认为如果buf传递给on_data_recv_fn的{​​{1}}是由某些C代码动态分配的,那么后来会尝试释放它。另一个危险的可能性:该函数是在Swift中实现的回调并由C代码调用。在这种情况下,buf可能在堆栈中。

我没有玩过任何这些场景,但根据NSData文档,bytesNoCopy初始值设定项使NSData取得内存的所有权,然后取消分配;它假设内存是使用malloc()分配的,因此任何不是malloc'd的内存都不应该用于使用此初始化程序构造NSData。见https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSData_Class/#//apple_ref/occ/instm/NSData/initWithBytesNoCopy:length

还有其他NSData初始化程序可以复制缓冲区,在这些情况下可以更安全。