2013-12-18 37 views
0

在我的應用程序中我正在從設備中獲取聯繫人列表, 這一切都按計劃進行,直到我到達發佈行。iOS發佈參考iPhoneContactList與ARC

應用程序根據需要進行編譯,但在運行時它只是停下來,指向發行行,並告訴綠色發光文本訪問不良。

這裏是我的代碼: 我自己的隊列調用GCD(因爲它是一個大的過程中,我在後臺做了,我不知道如果我要使用@autoreleasepool

我跑產品 - 功能>分析和這裏的東西在這個功能我在留言中加入。

-(void)getContacts 
{ 
@autoreleasepool { 
ABAddressBookRef iPhoneAddressBook = ABAddressBookCreateWithOptions(NULL, NULL); 
__block BOOL accessGranted = NO; 
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6 
    dispatch_semaphore_t sema = dispatch_semaphore_create(0); 
    ABAddressBookRequestAccessWithCompletion(iPhoneAddressBook, ^(bool granted, CFErrorRef error) 
    { 
     accessGranted = granted; 
     dispatch_semaphore_signal(sema); 
    }); 
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 
} 
else { // we're on iOS 5 or older 
    accessGranted = YES; 
} 
if (accessGranted) 
{ 
    CFErrorRef error = nil; 
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error); // indirection 
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook); 
    NSMutableArray* EmailArrayPerPerson = [[NSMutableArray alloc]init];//value stored to EMailArrayPerPerson during its initialization is never read 
    NSMutableArray* PhoneArrayPerPerson = [[NSMutableArray alloc]init];//value stored to PhoneArrayPerPerson during its initialization is never read 
    for (int i = 0; i < ABAddressBookGetPersonCount(addressBook); i++)//potential leak of an object stored in to contact 
    { 
     NSMutableDictionary *ContactsDetails = [NSMutableDictionary dictionary]; 
     ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i); 
     NSString *contact = (__bridge NSString *)(ABRecordCopyCompositeName(ref)); 
     if([contact length] <=0) 
      continue; 
     ContactsDetails = [NSMutableDictionary dictionary]; 
     [ContactsDetails setObject:contact forKey:@"CName"]; 
     ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty); 
     EmailArrayPerPerson = [[NSMutableArray alloc]init]; 

     NSLog(@"dictionary is:%@",[ContactsDetails objectForKey:@"CName"]); 
     for (CFIndex j=0; j < ABMultiValueGetCount(emails); j++) 
     { 
      NSString* email = (NSString*)CFBridgingRelease(ABMultiValueCopyValueAtIndex(emails, j)); 
      [EmailArrayPerPerson addObject:email]; 
     } 
     [ContactsDetails setObject:EmailArrayPerPerson forKey:@"CEMails"];//potential leak in emails 
     ABMultiValueRef multi = ABRecordCopyValue(ref, kABPersonPhoneProperty); 
     PhoneArrayPerPerson = [[NSMutableArray alloc]init]; 
     for (CFIndex j=0; j < ABMultiValueGetCount(multi); j++) 
     { 
      NSString* phone = (NSString*)CFBridgingRelease(ABMultiValueCopyValueAtIndex(multi, j)); 
      [PhoneArrayPerPerson addObject:phone]; 
     } 
     [ContactsDetails setObject:PhoneArrayPerPerson forKey:@"CPhones"]; 
     [Contacts addObject:ContactsDetails]; 
      CFRelease(ref);//incorect decrement of the reference count of an object that is not owned at this point by the caller. 
      CFRelease(multi); 
    } 
    CFRelease(allPeople);//Potential leak of an object stored in to addressBook 
    // CFRelease(addressBook);// *strange issue with bad access is here* 
} 
else 
{ 
    CFRelease(iPhoneAddressBook); 
    return; 
} 
} 
} 

我知道這是大的功能,但我想我不得不將其添加爲的就是讓一切都清楚了。 我很新的iOS SDK如此請你能向我解釋一下在訪問不好的情況下發生了什麼 那裏 ?

我不確定,但我認爲addressBook是冗餘分配,因爲我已經分配了iPhoneAddressBook我不確定。 (我也不確定我是否要釋放它(因爲我正在使用ARC,但ARC不應該爲我釋放crefs))。

+0

您是否嘗試過在Xcode中使用Product-> Analyze來查找可能的內存管理問題? –

+0

@MartinR不,如我所說我是新來的Xcode和iOS 我會嘗試它,謝謝你的建議! 我的意思是我不知道它是什麼,我只是用google搜索那樣的東西。 –

+0

分析發現23個問題他們中的大多數都是'死商店',在這個特定功能中發現了一些其他問題。使用分析結果更新我的問題 –

回答

2

主要問題似乎是在這裏:

ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i); 
// ... 
CFRelease(ref); // <-- WRONG 

CFArrayGetValueAtIndex()沒有在其名稱中的「創建」或「複製」,所以你 沒有「自己的」返回的對象,不能釋放。 有關更多信息,請參閱「用於Core Foundation的內存管理編程指南」中的"Ownership Policy"

爲了解決contact的潛在泄漏,通過

NSString *contact = (__bridge_transfer NSString *)(ABRecordCopyCompositeName(ref)); 

ABRecordCopyCompositeName()其名稱中有 「複製」 取代

NSString *contact = (__bridge NSString *)(ABRecordCopyCompositeName(ref)); 

,所以你自己返回的對象。 __brigde_transfer將所有權「轉讓」給ARC,以便在contact超出範圍時發佈對象 。

+0

因爲我得到它的價值而不是參考。是的,這是有道理的,我會修復它,然後運行代碼,再次發佈addressBook –

+0

是的,作爲魅力工作非常感謝你:)你還可以看看'addressBook'上面的行發佈它說潛在的物體泄漏存儲在'addressBook'中? –

+0

哦,非常感謝你,關於死商店,我看到它更像是一個警告消息,我沒有看到我必須做些什麼吧? –