[英]Releasing a C type declared as an Objective-C property
我已經聲明C類型為我的Objective-C對象的屬性。 我想確保我的財產正被ARC正確收集到垃圾。
僅僅重復幾次就不會泄漏內存,但是由於我還沒有找到關於該主題的適當文檔,因此我想確認一下。
基本上,當我覆蓋dealloc
以釋放C類型時,出現錯誤,我的變量從未分配:
malloc:***對象錯誤:未分配要釋放的指針***
在malloc_error_break中設置一個斷點進行調試
@interface MyClass : NSObject
@property (readonly, assign) xmlDocPtr doc;
@end
@implementation MyClass
- (void)dealloc {
if (_doc != NULL) {
xmlFreeDoc(_doc); // throwing da runtime error, see above!
}
NSLog(@"dealloc'ed!"); // call me please T___T
}
// Setting my C-type property here:
- (instancetype)initWithFileAtPath:(NSString *)path {
NSData *data = [[NSFileManager defaultManager] contentsAtPath:path];
[self setDoc:htmlReadMemory([data bytes], (int)[data length], "", NULL, HTML_PARSE_NOWARNING | HTML_PARSE_NOERROR)];
if (_doc == NULL) return nil;
NSLog(@"init'ed!"); // gets called!
return self;
}
// Property setter (as suggested by DarkDust):
- (void)setDoc:(xmlDocPtr)doc {
if (_doc != NULL) xmlFreeDoc(_doc);
_doc = doc;
}
@end
由於ARC只能對Objective-C對象進行操作,因此它無法幫助您管理C類型。
正確管理內存的關鍵問題始終是“誰'擁有'對象?” 在Objective-C中,這是使用引用計數和明確的命名規則來完成的。 由於C類型沒有此功能,因此需要小心。
那么,誰在創建您的xmlDoc
實例? 如果與您為其編寫了dealloc
方法的對象相同(讓我們調用該類Foo
),而您只想通過該屬性公開該實例,則所有權是明確的: Foo
是實例的所有者,因此需要清除起來。 在這種情況下,您已經在dealloc
中做到了(盡管那里有一個bug;變量本身總是有一個地址,所以&_doc
永遠不會為NULL!)。 我將屬性設置為只讀,以避免任何人從外部弄亂指針(要對其進行分配,則需要直接訪問后備變量_doc
)。 因此,它看起來像這樣:
@property(readonly, assign) xmlDocPtr doc;
...
_doc = CreateTheXMLDocInstance();
...
- (void)dealloc {
if (_doc != NULL) xmlFreeDoc(_doc);
}
如果您實際上想使該屬性可寫,則需要正確處理設置器。 同樣,問題是:誰擁有實例? 如果您希望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
取消分配_doc
。
現在,對於您的運行時錯誤,您在更新問題后已引用了該錯誤消息:錯誤消息告訴您某人正在嘗試釋放不是malloc
返回值的地址。 很有可能,分配給_doc
的值不是有效的指針,或者至少不是指向malloc
返回的內存塊開頭的指針。 反過來,這意味着該錯誤必須在htmlReadMemory
函數中的某個htmlReadMemory
:它不會返回有效的xmlDocPtr
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.