释放声明为Objective-C属性的C类型
我已将C类型声明为Objective-C对象的属性。我想确保我的财产被ARC正确收集垃圾 仅仅迭代多次不会泄漏内存,但由于我还没有找到关于这个主题的适当文档,我想确认一下 基本上,当我重写释放声明为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类型 正确管理内存的一个重要问题始终是“谁‘拥
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;
}