float* cubedata = (float*)malloc(cubedataSize);printf("cubedata=%p\n",cubedata);// cubedata=0x01beef00for (...) { /* fill the cubedata array */ }NSData* data = [NSData dataWithBytesNocopy:cubedata length:cubedataSize freeWhenDone:YES];NSData* data2 = [data copyWithZone:nil]printf("data.bytes=%p data2.bytes=%p\n",data.bytes,data2.bytes);// data.bytes=0x01beef00 data2.bytes=0x01beef00
对我来说没关系,copyWithZone不会对malloc的区域进行深度复制 – 如果我想要深层复制,我可以使用[NSData dataWithData:].我不清楚(我不确定如何最好地测试)是哪个NSData对象拥有底层的malloc缓冲区?如果他们都持有对malloc缓冲区的引用(使用某种形式的不透明引用计数)那就太棒了!但是,如果释放数据对象时释放malloc缓冲区(如freeWhenDone:YES所暗示的那样),则data2将无法解决问题.
有人可以解释NSData在这种情况下做了什么吗?或者,有人可以建议一个明确的测试,以证明自己发生了什么?
解决方法 对于基本问题:Is the content of NSData separately reference-counted?
不.(但是看看你的代码,它应该没关系.在这种转移之后见下文.)
—开始转移—
ARC通过在适当的时间发送等效的保留和释放消息来管理Objective-C对象的保留和释放.通过代码检查在编译时确定“适当的时间”.这正是它所做的一切.当您开始创建指向这些对象的非对象片段(即字节)的指针时,您可以自己管理生命周期.
@CouchDeveloper提供了有关objc_precise_lifetime的良好信息.在处理内部指针时,将此属性放在数据对象上可以保护您免受ARC优化,但这在此处并不重要. objc_precise_lifetime的要点是告诉ARC,在引用变量超出范围之前,不允许释放对象.它解决的问题看起来像这样:
NSData *data = ...;voID *stuff = data.bytes; // (1)doSomething(stuff); // (2)
ARC有an optimization表示它允许在第(1)行和第(2)行之间销毁数据,因为即使数据在范围内,你也不会再次引用数据.添加objc_precise_lifetime属性以禁止该优化.当您开始大量使用NSData时,此属性可能变得很重要.
—结束转移—
好的,但你的情况怎么样?
float* cubedata = (float*)malloc(cubedataSize);NSData* data = [NSData dataWithBytesNocopy:cubedata length:cubedataSize freeWhenDone:YES];NSData* data2 = [data copyWithZone:nil]
在运行此代码之后,有两种可能性(并且您不应该关心大部分时间,因为这些是不可变对象):
> data和data2都是同一NSData对象的强指针.该对象拥有malloced内存,并在释放时释放它. (在这种特殊情况下几乎肯定会发生这种情况,但这是一个实现细节.)
>数据指向拥有malloced内存的NSData对象,并在释放时释放它. data2指向具有自己内存的不同NSData对象(在解除分配时它将释放.)
(还有其他选择;也许NSData使用底层dispatch_data或写时复制方案.但是所有选项应该从外部有效地看起来如上所述.)
在第一种情况下,如果数据超出范围,但data2仍然存在,则保留拥有的NSData.没问题.在第二种情况下,当数据超出范围时,它会破坏其内存,但data2有一个独立的副本,所以再次没问题.
我认为你的困惑来自于认为数据拥有内存.它没有.数据指向拥有内存的NSData对象.数据和数据2只是指针.
总结以上是内存溢出为你收集整理的ios – NSData的内容是否单独引用计数?全部内容,希望文章能够帮你解决ios – NSData的内容是否单独引用计数?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)