簡體   English   中英

如何使通訊錄成為一類的財產?

[英]How should an address book be made a property of a class?

我有一個訪問通訊錄的類,如果我有以下代碼,那么我會從分析器得到警告,一個是針對init方法的泄漏,另一個是說該類在釋放對象時不擁有該對象。解除分配。

我認為第二個警告是由於將通訊錄ref聲明為assign? 但這無法使其強大,因為這會生成編譯警告。 將通訊錄視為財產的正確方法是什么?

@property (assign, nonatomic)   ABAddressBookRef                addressBook;

..
- (id) init
{
    self = [super init];
    if (self)
    {
        if (ABAddressBookCreateWithOptions)
        {
            // iOS 6 onwards
            self.addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
        }
        else
        {
            // < iOS 6
            self.addressBook = ABAddressBookCreate();
        }
    }
    return self;
}


- (void) dealloc
{
    if (self.addressBook)
    {
        CFRelease(self.addressBook);
    }
}

這是一個誤報,您在dealloc方法中使用CFRelease調用正確平衡了retainCount的初始+1。

您可以使用ivar代替屬性來初始化和釋放指針,從而擺脫警告。

- (id) init {
    // ...
    _addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    //...
}

- (void)dealloc { 
    CFRelease(_addressBook); //assuming that _addressBook is your synthesized ivar
}

這在技術上是真實的,你沒有自己的地址簿,因為assign屬性不應該是擁有引用。 您班上的一個客戶可能會覆蓋通訊錄參考,而您會泄漏它。

完全解決該問題的一種方法是為您的地址簿創建一個顯式聲明的字段,並為其設置一個只讀屬性,然后僅從類內部處理該字段,而不是該屬性。 由於不能分配只讀屬性,因此不用懷疑它們是否擁有引用。

我不在Mac前面,因此無法測試,但即使這不是Objective-C對象,也可以使用retain ed屬性。 許多Core Foundation對象以Objective-C標頭開頭,並響應幾種NSObject方法。 如果您不能使其與@synthesize ,我認為您仍然可以自己手動實現方法,而不會受到編譯器的抱怨。

這是我使用的解決方案

@synthesize addressBook = _addressBook;
- (ABAddressBookRef)addressBook{
    if (_addressBook == nil){
        if (ABAddressBookCreateWithOptions != NULL){
            _addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
        }
        else {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
            _addressBook = ABAddressBookCreate();
#pragma GCC diagnostic pop
        }

        if (![self requestAddressBookAuthorizationWithAddressBook:_addressBook]){
            _addressBook = nil;
        }

    }
    return _addressBook;
}
- (void)setAddressBook:(ABAddressBookRef)addressBook{
    if (_addressBook != addressBook){
        if (_addressBook != nil){
            CFRelease(_addressBook);
        }

        _addressBook = nil;

        if ([self requestAddressBookAuthorizationWithAddressBook:addressBook]){
            _addressBook = addressBook;
        }
        if (_addressBook != nil){
            CFRetain(_addressBook);
        }
    }
}

此時,您可以將屬性設置為nil,並且setter將處理擺脫保留的問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM