2009-05-15 8 views
20

Muss ich Core Foundation-Objekte freigeben, um Arbeitsspeicher zu löschen? Und wenn ja, wie?Releasing Core Objektreferenzen

Zum Beispiel im Code:

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

ich peopleArray lösen müssen? Was ist mit addressBook?

Antwort

26

Ja, in CoreFoundation müssen Sie alles mit Create oder Copy im Namen freigeben. Sie tun dies mit CFRelease(). In Ihrem Fall sollten Sie sowohl das Array als auch die Adressbuchverweise freigeben.

+0

Vielen Dank. Ich habe darum gekämpft, die Antwort auf Google zu finden. Wahrscheinlich, weil ich nach "Core Framework" anstatt nach "Core Foundation" gegoogelt habe. Do! :) – rein

3

Ich würde empfehlen, Apples guide auf Core Foundation Memory Management für eine eingehende Diskussion dieser zu lesen. Sie haben einen ähnlichen Leitfaden für das allgemeine Cocoa-Speichermanagement.

Um ein CF-Objekt freizugeben, rufen Sie die CFRelease-Funktion auf.

26

Die rules für Speicherverwaltung in Core Foundation sind denen in Cocoa ähnlich: Wenn die Methode, die eine Referenz zurückgibt, die Wörter "create" oder "copy" enthält, müssen Sie die Referenz besitzen und CFRelease() für diese Referenz aufrufen, um aufzugeben Eigentum. Andernfalls tun Sie nicht besitzen die Referenz und müssen CFRetain aufrufen, um das Eigentum zu übernehmen (notwendigerweise eine nachfolgende CFRelease erforderlich, um diese neue Eigentümerschaft aufzugeben). Diese Regeln, wie aus dem Memory-Management-Programmierhandbuch für Core Foundation genommen sind:

  • Wenn Sie ein Objekt erstellen (entweder direkt oder durch eine Kopie macht eine anderes objekt siehe „Das Erstellen -Regel“), Es gehört dir.
  • Wenn Sie ein Objekt von woanders bekommen, tun Sie nicht besitzen. Wenn Sie verhindern möchten, dass entsorgt wird, müssen Sie als Eigentümer hinzufügen (unter Verwendung von CFRetain).
  • Wenn Sie ein Eigentümer eines Objekts sind, müssen Sie den Besitz auflösen, wenn Sie die Verwendung (mit CFRelease) beendet haben.

In Ihrem Beispiel müssen sowohl die addressBook als auch die peopleArray freigegeben sein. Da in Core Foundation kein autorelease Äquivalent vorhanden ist, geben Sie das Array ohne zurück, wenn Sie die Referenz aus einer Methode zurückgeben. Sie sollten (sofern Sie nicht böse sind) dann "create" in den Methodennamen aufnehmen, um dem Aufrufer anzuzeigen, dass er jetzt einen Verweis auf das zurückgegebene Objekt besitzt. In diesem Fall ist CFArray gebührenfrei überbrückt zu NSCFArray, ein Objective-C-Objekt, das von NSObject erbt. Sie können werfen somit peopleArray zu einem NSArray* und autorelease, dass, wenn Sie es von einer Funktion/Methode zurückgeben müssen:

return [(NSArray*)peopleArray autorelease]; 

beachten, dass dies nur funktioniert, für gebührenfreie überbrückte Klassen. Mein Verständnis ist, dass es ziemlich schwierig ist, eigene gebührenfreie gebrückte Klassen zu bilden, und nur die primitiven (String, Array, etc.) CF-Klassen sind gebührenfrei überbrückt, so dass dieser Ansatz nicht immer funktioniert. Schließlich, wenn Sie vermeiden können, autorelease (d. H.Sie können Ihre Speicherverwaltung expliziter machen), das ist wahrscheinlich immer eine gute Sache.

+0

Danke Barry - Ich bin sehr versiert in den Speicherregeln von Cocoa - ich war mir einfach nicht sicher, ob die CF-Regeln die gleichen waren. Schön zu wissen, dass sie es sind. – rein

+0

Das gleiche, abgesehen von der fehlenden Autorelease ... Wenn Sie mit den Cocoa-Regeln vertraut sind und möglichst keine automatische Freigabe benötigen, sind Sie vollkommen zuhause. –

+1

Objekte, die gebührenfrei überbrückt werden, können durch Senden an die ID automatisch freigegeben werden: [(id) cfObject autorelease]; – rpetrich

4

Ein weiterer kleiner Punkt, den noch niemand erwähnt hat, einige CF-Klassen haben eine "gebührenfreie Brücke" mit ihrem NS-Pendant. CFString und NSString, CFArray und NSArray sind beide Beispiele. Dies ist relevant, da Sie einfach release mit diesen Klassen verwenden können.

Weitere Informationen finden Sie unter other StackOverflow question.

3

Für ARC können Sie verwenden.

return (__bridge_transfer NSArray*)peopleArray; 

„__bridge_transfer“ wird das Eigentum an ARC übertragen und daher müssen Sie keine weiteren Release Anruf.

Verwandte Themen