簡體   English   中英

當UITableView充滿了AddressBook中的信息時,應用程序崩潰

[英]App crashes when UITableView filled with info from AddressBook scrolls down

我正在嘗試在我的應用程序中實現一項功能,該功能要求我在用戶手機中顯示所有包含電子郵件的聯系人。

我成功地從Address Book框架中檢索了相關的聯系人,並將信息保存在一個數組中。 每個聯系人都包裝在包裝中,其中包含2個屬性: fullNameemail ,它們都是NSString

現在,我已經在視圖控制器中的表格中填充了聯系人數組,當表格是靜態的而沒有任何用戶觸摸或滾動時,一切都很棒,生活也很棒! 但是,當我向下滾動以顯示更多聯系人時,我會崩潰!

碰撞

沒有日志轉儲到控制台。 我在tableView:cellForRowAtIndexPath:的其中一行上有一條綠線(與使用調試器進行斷點時相同) tableView:cellForRowAtIndexPath:表示以下內容: Thread 1: EXC_BAD_ACCESS (code=1, address=0x10d9eb4e)

我的調查

我對觸點數組有很強的參考。 我已經檢查了該數組的內容。 並注意到,用戶可見的所有項目(即大約11個項目)都是絕對有效的。 所有字段均與預期數據(全名和電子郵件)正確。

另一方面,數組中的其余項目似乎已損壞或某種原因。 我可以看到這些項目屬於NRContactInfo類型,其中具有2個屬性: _fullName_email但即使這2個屬性的類型是NSString ,內容也不是字符串,而是內存地址或其他內容(例如:0x114e2b3b0)。

我注意到崩潰是第一次在tableView:cellForRowAtIndexPath:中發生的,在這里我對NRContactInfo屬性之一進行了調用,因此,如果我要從tableView:cellForRowAtIndexPath:刪除對NRContactInfo屬性的所有調用,而只需使用dummy信息,那么一切都很好。

因此,我認為這與丟失從AddressBook檢索到的信息有關。 但我不知道為什么或如何解決它。

我的一些幫助者代碼 (已編輯)

UPDATE

為了清楚起見,我刪除了一些未連接的/不必要的代碼部分。 我添加了NRContactInfo類的實現。

這是tableView:cellForRowAtIndexPath:方法的代碼片段,該方法如上文所述崩潰。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"tableCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
    }

    NRContactInfo *contact = contacts[indexPath.row];

    cell.textLabel.text = contact.fullName;   // <------   CRASHES HERE!
    cell.detailTextLabel.text = contact.email;

    return cell;
}

在此先感謝您提供的所有信息,這些信息將幫助我解決此問題!

UPDATE

正如沃克·沃克金(Volker Voecking)在他的評論中指出的那樣,我將在此處發布從地址簿中檢索聯系信息並創建NRContactsInfo對象的代碼:

- (void)getPersonsOutOfAddressBook
{
//In case of an error we create an error object.
CFErrorRef error = NULL;
//We get a reference to the user's address book.
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if ([self checkForPermmissionsToAccessAddressBook:addressBook]){
    if (addressBook != nil) {
        NSLog(@"Succesful.");

        //we copy all contacts from the addressbook in an array
        NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);

        //We loop through the contacts in the address book. For each contact, we create a NRContactInfo Object.
        NSUInteger i = 0; for (i = 0; i < [allContacts count]; i++)
        {
            ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];

            NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
            NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
            NSString *fullName = @"";
            if (firstName) {
                fullName = [fullName stringByAppendingString:firstName];
            }
            if (lastName) {
                fullName = [fullName stringByAppendingString:@" "];
                fullName = [fullName stringByAppendingString:lastName];
            }
            NSString *email;

            //The email property of the addressbook is assigned to a multivalue reference
            ABMultiValueRef emails = ABRecordCopyValue(contactPerson, kABPersonEmailProperty);

            if (ABMultiValueGetCount(emails)>0){
                NSUInteger j = 0;
                for (j = 0; j < ABMultiValueGetCount(emails); j++) {
                    email = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(emails, j);
                    NRContactInfo *contact =[NRContactInfo initWithFullName:fullName Email:email];
                    if (contact.isValid)
                        [_contacts addObject:contact];
                }
            }
        }
        CFRelease(addressBook);
    } else { 

        NSLog(@"Error reading Address Book: %@", error);
    }
}

}

- (BOOL)checkForPermmissionsToAccessAddressBook:(ABAddressBookRef) addressBook
{
    __block BOOL userDidGrantAddressBookAccess = NO;

    if ( ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined ||
        ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized ) {
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error){
            userDidGrantAddressBookAccess = granted;
        });
    }
    else {
        if ( ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusDenied ||
            ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusRestricted ) {
            // Display an error.
        }
    }
    return userDidGrantAddressBookAccess;
}

NRContactInfo的實現:

+ (NRContactInfo *)initWithFullName:(NSString *)fullName Email:(NSString *)email
{
    NRContactInfo *contact = [NRContactInfo new];

    contact.fullName = [NSString stringWithFormat:@"%@", fullName];
    contact.email = [NSString stringWithFormat:@"%@", email];

    return contact;
}

- (BOOL)isValid
{
    if (_fullName &&_email)
        return YES;
    return NO;
}

在編輯我的答案以使其更准確並包含有關我的問題的更多信息時,我注意到了問題的根源:

在我的NRContactInfo類中,我有2個屬性,它們聲明如下:

@property (nonatomic, assign) NSString *fullName;
@property (nonatomic, assign) NSString *email;

這就是奇怪的崩潰的原因。 顯然,即使我確定我對這些屬性都有有效的引用,但我沒有!

這是解決我的問題的原因:

@property (nonatomic, retain) NSString *fullName;
@property (nonatomic, retain) NSString *email;

感謝所有幫助者,並感謝所有其他注意復制和粘貼罪過的人:D

暫無
暫無

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

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