20

我是否需要释放核心基础对象来清理内存?如果是这样,怎么办?

例如,在代码中:

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef peopleArray = ABAddressBookCopyArrayOfAllPeople(addressBook);

我需要释放peopleArray吗?怎么样addressBook

4

5 回答 5

26

是的,在 CoreFoundation 中,您必须发布名称中带有 Create 或 Copy 的任何内容。您可以使用 CFRelease() 执行此操作。在您的情况下,您应该同时发布数组和地址簿引用。

于 2009-05-15T18:50:28.673 回答
26

Core Foundation 中的内存管理规则类似于 Cocoa 中的规则:如果返回引用的方法包含“创建”或“复制”字样,则您拥有该引用,并且必须调用该CFRelease()引用以放弃所有权。否则,您拥有该引用并且必须调用CFRetain以获取所有权(必然要求后续CFRelease放弃该新所有权)。这些规则取自 Core Foundation 的内存管理编程指南:

  • 如果您创建一个对象(直接或通过复制另一个对象——请参阅“创建规则”),您就拥有它。
  • 如果你从其他地方得到一个对象,你就不拥有它。如果您想防止它被丢弃,您必须将自己添加为所有者(使用 CFRetain)。
  • 如果您是对象的所有者,则必须在使用完毕后放弃所有权(使用 CFRelease)。

在您的示例中,必须释放theaddressBook和 the 。peopleArray由于 Core Foundation 中没有autorelease等效项,因此如果您从方法返回引用,请返回数组而不释放它。您应该(除非您是邪恶的)然后在方法名称中包含“create”,以向调用者表明他们现在拥有对返回对象的引用。在这种情况下,CFArray 被免费桥接到NSCFArray,一个继承自 的 Objective-C 对象NSObject。因此,如果您需要从函数/方法返回它,您可以peopleArray转换为NSArray*and that:autorelease

return [(NSArray*)peopleArray autorelease];

请注意,这仅适用于免费桥接课程。我的理解是,制作自己的免费桥接类相当困难,并且只有原始(字符串、数组等)CF 类是免费桥接的,因此这种方法并不总是有效。最后,如果您可以避免使用autorelease(即您可以使您的内存管理更加明确),那可能总是一件好事。

于 2009-05-15T18:51:53.477 回答
4

另一个没有人提到的小点是,一些 CF 类与他们的 NS 类有一个“免费桥”。CFStringNSStringCFArray都是NSArray示例。这是相关的,因为您可以只使用release这些类。

有关更多信息,请参阅其他 StackOverflow 问题

于 2009-05-15T19:08:46.103 回答
3

我建议阅读 Apple 关于 Core Foundation 内存管理的指南,以深入讨论这一点。他们也有一个类似的通用 Cocoa 内存管理指南。

要释放 CF 对象,您将调用该CFRelease函数。

于 2009-05-15T18:51:33.647 回答
3

对于 ARC,您可以使用。

return (__bridge_transfer NSArray*)peopleArray;

"__bridge_transfer" 会将所有权转移给 ARC,因此您不需要任何进一步的发布调用。

于 2012-05-05T20:14:50.490 回答