Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.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
释放声明为Objective-C属性的C类型_Objective C_C_Memory Management - Fatal编程技术网

释放声明为Objective-C属性的C类型

释放声明为Objective-C属性的C类型,objective-c,c,memory-management,Objective C,C,Memory Management,我已将C类型声明为Objective-C对象的属性。我想确保我的财产被ARC正确收集垃圾 仅仅迭代多次不会泄漏内存,但由于我还没有找到关于这个主题的适当文档,我想确认一下 基本上,当我重写dealloc以释放我的C类型时,我得到一个错误,我的变量从未分配: malloc:**对象错误:未分配要释放的指针*** 在malloc\u error\u break中设置断点以进行调试 由于ARC只能对Objective-C对象进行操作,因此它无法帮助您管理C类型 正确管理内存的一个重要问题始终是“谁‘拥

我已将C类型声明为Objective-C对象的属性。我想确保我的财产被ARC正确收集垃圾

仅仅迭代多次不会泄漏内存,但由于我还没有找到关于这个主题的适当文档,我想确认一下

基本上,当我重写
dealloc
以释放我的C类型时,我得到一个错误,我的变量从未分配:

malloc:**对象错误:未分配要释放的指针***
在malloc\u error\u break中设置断点以进行调试


由于ARC只能对Objective-C对象进行操作,因此它无法帮助您管理C类型

正确管理内存的一个重要问题始终是“谁‘拥有’对象?”在Objective-C中,这是通过引用计数和清晰的命名规则来实现的。因为C类型没有这种功能,所以需要小心

那么,谁在创建您的
xmlDoc
实例呢?如果它是您为其编写了
dealloc
方法的同一个对象(我们将该类称为
Foo
),并且您只想通过属性公开该实例,那么所有权是明确的:
Foo
是实例的所有者,因此需要清理它。在本例中,您已经在
dealloc
中执行了此操作(尽管您有一个bug;变量本身总是有一个地址,因此
&\u doc
将永远不会为NULL!)。我会将属性设置为只读,以避免任何人从外部弄乱指针(要分配它,您需要直接访问支持变量
\u doc
)。这样看来:

@property(readonly, assign) xmlDocPtr doc;

...
_doc = CreateTheXMLDocInstance();
...

- (void)dealloc {
    if (_doc != NULL) xmlFreeDoc(_doc);
}
如果您确实希望使属性可写,则需要正确处理setter。同样,问题是:谁拥有这个实例?如果您想让
Foo
对象成为唯一的所有者,事情实际上相当简单。您只需编写一个自定义setter来取消分配旧实例:

- (void)setDoc:(xmlDocPtr)doc {
    // Do not free if it's the same pointer.
    if (doc == _doc) return;
    // Remove old instance, if we have one.
    if (_doc != NULL) xmlFreeDoc(_doc);
    // Assign new instance.
    _doc = doc;
}

如果
Foo
对象不是唯一所有者,则不允许在setter或
dealloc

中释放
\u doc
,因为您在更新问题后引用的运行时错误:错误消息告诉您有人试图释放一个不是
malloc
。很可能,分配给
\u doc
的值不是有效指针,或者至少不是指向
malloc
返回的内存块开头的指针。这反过来意味着错误一定在
htmlReadMemory
函数中的某个地方:它不会返回有效的
xmlDocPtr

我想你的意思是
如果(\u doc!=NULL)xmlFreeDoc(\u doc)不带
。如果这不能解决问题,请更新您的问题,分享您收到的编译器错误。@Rob编辑了我的超级棒的帖子!这个修改过的样品对我来说很好。它对我来说运行正常。你确定你不会有一个
xmlFreeDoc
在别处徘徊吗?@Rob nope,指针的整个生命周期都在那里。好的。如果没有,我无法提供进一步的建议。祝你好运。我添加了更多代码供你查看。基本上还是遇到同样的问题。。。我放置
的原因是为了排除故障。我删除了它并添加了
readonly
assign
指令。C类型的创建者是对象本身。我认为它恰好在初始化方法中并不重要。我想,所有者仍然是拥有属性的类。setter实现是错误的。你在那里没有所有权,所以你也不应该在那里自由。当doc==\u doc时也无效。@Sulthan我正在实现DarkDust建议的setter,但它仍然会引发相同的错误。编辑文章以反映这一点。此外,如果C类型所有者被声明为属性并设置在对象内部,那么它与对象本身又有什么不同呢?@Sulthan:doc==\u doc==\u doc
(修复了setter)这一点很好,但是“你没有取得所有权”是什么意思呢?如果对象应该成为
xmlDocPtr
的新的唯一所有者,那么setter应该是这样的。不过,我可以访问返回的xmlDocPtr的成员。
- (void)setDoc:(xmlDocPtr)doc {
    // Do not free if it's the same pointer.
    if (doc == _doc) return;
    // Remove old instance, if we have one.
    if (_doc != NULL) xmlFreeDoc(_doc);
    // Assign new instance.
    _doc = doc;
}