[英]App crashes when UITableView filled with info from AddressBook scrolls down
我正在嘗試在我的應用程序中實現一項功能,該功能要求我在用戶手機中顯示所有包含電子郵件的聯系人。
我成功地從Address Book
框架中檢索了相關的聯系人,並將信息保存在一個數組中。 每個聯系人都包裝在包裝中,其中包含2個屬性: fullName
和email
,它們都是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.