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 导致数据泄漏的NSD_Ios_Swift_Swift2_Nsdata - Fatal编程技术网

Ios 导致数据泄漏的NSD

Ios 导致数据泄漏的NSD,ios,swift,swift2,nsdata,Ios,Swift,Swift2,Nsdata,我有一个Cchar*cArray和它的长度,我需要将它转换为NSData 我是这样做的: var data: NSData? = NSData(bytesNoCopy: cArray, length: Int(length)) 它正在工作。问题是这会导致内存泄漏。我不知道为什么,但我可以在分配工具上看到它是malloc 64字节,当函数完成或我将其设置为null时不会释放它 这段代码被调用了很多,所以我需要它是免费的泄漏。我能做些什么来防止泄漏 编辑:这是代码 func on_data_rec

我有一个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)
}
func on_data_recv_fn(buf:UnsafeMutablePointer,length:CInt,user_data:UnsafeMutablePointer)->CInt{
守卫buf!=没有其他{
NSLog(“数据记录中的buf为零”)
返回-1
}
//var数据:NSData?=NSData(字节nocopy:buf,长度:Int(长度),自由时长:true)
var数据:NSData?=NSData(字节nocopy:buf,长度:Int(长度))
让succeeedwriting=Int(PacketTunnelProvider.sendpackages(数据!))
数据=零
返回CInt(成功写入)
}
根据记忆仪器,这里有个漏洞。 sendPackets函数不保存数据,因此不存在问题

编辑:附加来自仪器的图像。

好吧,似乎由于某种原因,如果我使用autoreleasepool,一切都正常

由Objective-C支持的类型的内存管理是一个广泛而有趣的话题。例如,请参见此处:

您可能还发现这个问题很有用:

另外,如果传递给
on_data\u recv\u fn
buf
是由某个C代码动态分配的,该代码稍后会尝试释放它,那么我认为这里有一个危险。另一种危险的可能性是:该函数是用Swift实现的回调函数,由C代码调用。在这种情况下,
buf
可能位于堆栈上

我没有玩过这些场景,但根据
NSData
文档,
bytesnopy
初始值设定项使
NSData
获得内存的所有权,然后取消分配它;它假定内存是使用
malloc()
分配的,因此任何未使用
malloc的内存都不应使用此初始值设定项来构造
NSData
。见:


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

如果触发内存警告会发生什么?内存是否被释放?bytesNoCopy初始值设定项不分配任何数据,它只获取给定的数据并将其包装到NSData对象中。奇怪的是,你在这一点上看到了malloc。你确定吗?缓冲区是从哪里来的?您需要确保它最终被解除分配。如果数据是用malloc分配的,那么NSData bytesNoCopy也将在解除分配NSData对象时解除分配。所以OP在这里应该只看到一个免费的但没有malloc。但是OP只看到一个malloc,没有免费的。真奇怪。我假设:仪器输出被曲解了。这是一个很好的问题。代码的细节似乎混淆了真正的问题。当我试图将使用arc编译的对象文件与那些被编码来执行自己的retain和release调用的对象文件混合使用时,我也发生了内存泄漏。我还从一个malloc'ed缓冲区创建了NSData对象,这个缓冲区是我从一个c代码获得的。我确信NSData本身正在泄漏一些东西,即使我将文件转换为手动内存管理并自己发布了NSData。但你下面的解决方案成功了。将该块包装在@autoreleasePool{}块中,泄漏就消失了。