0

我在使用通讯簿将联系人姓名从设备获取到我自己的应用程序中的联系人视图时遇到了一些问题。

我的代码在模拟器上运行良好,但是当我在 iPhone 4 上测试时它会崩溃,如果有两个或更少的联系人但 3 个或更多并且应用程序崩溃,应用程序似乎工作正常。

这是我用来将联系人姓名放入数组的代码。

    ABAddressBookRef addressBook;
    bool wantToSaveChanges = YES;
    bool didSave;
    CFErrorRef error = NULL;

    addressBook = ABAddressBookCreate();

    listOfContacts = [[NSMutableArray alloc]init]; 

    int i;
    int len = (int) ABAddressBookGetPersonCount(addressBook);
    for(i = 1; i< (len+1); i++){

        ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, (ABRecordID) i);
        NSString* name = (NSString *)ABRecordCopyCompositeName(person);
        ABMultiValueRef number = (NSString *)ABRecordCopyValue(person,kABPersonPhoneProperty);
        NSString *mobileNum = (NSString *)ABMultiValueCopyValueAtIndex(number, 0 );

        NSLog(@"Name = %@", name);
        NSLog(@"Number = %@", mobileNum);

        [listOfContacts addObject:name]; 

        [name release];
        [mobileNum release];


    }


    if(ABAddressBookHasUnsavedChanges(addressBook)){
        if(wantToSaveChanges){
            didSave = ABAddressBookSave(addressBook, &error);
            if(!didSave){
                //Error
            }
        }
        else{
            ABAddressBookRevert(addressBook);
        }
    }

当它崩溃时,这是在 Xcode 中突出显示的行:

NSString* name = (NSString *)ABRecordCopyCompositeName(person);

错误指出:

Thread 1: Program received signal: "EXC_BAD_ACCESS"

谁能看到问题可能是什么?我不明白为什么它可以在模拟器上运行但不能在设备上运行?还有为什么它适用于最多两个联系人而不是 3 个或更多联系人?

4

3 回答 3

4

只是一个猜测:

ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, (ABRecordID) i);

这条线对我来说看起来很可疑。我怀疑记录 ID 的编号是从 1 到什么。特别是如果您删除了一个条目。

这可以解释为什么它可以在模拟器上运行,我猜你只是添加了一些测试联系人并且从未删除过。

于 2011-04-26T15:17:07.413 回答
2

这是我解决它的方法:(
注意我如何确保只调用活动记录,我还创建了一个自定义的联系人类)
此代码处理边缘情况,例如:电子邮件/电话不存在,或存在不止一次。 ..

+(NSArray *)getAddressBook{
    ABAddressBookRef addressBook;
    bool wantToSaveChanges = YES;
    bool didSave;
    CFErrorRef error = NULL;

    addressBook = ABAddressBookCreate();

    NSMutableArray *listOfContacts = [[NSMutableArray alloc]init]; 
    CFArrayRef array=ABAddressBookCopyArrayOfAllPeople(addressBook);

    int len=CFArrayGetCount(array);

    for (int i = 0; i<len; i++){
        ABRecordRef person = CFArrayGetValueAtIndex(array, i);
        if (ABRecordGetRecordType(person)==kABPersonType){

            NSString *firstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
            NSString *lastName = (NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);

            ABMultiValueRef emails = (ABMultiValueRef)ABRecordCopyValue(person,kABPersonEmailProperty);
            ABMultiValueRef numbers = (ABMultiValueRef)ABRecordCopyValue(person,kABPersonPhoneProperty);

            int sumEmails=ABMultiValueGetCount(emails);
            int sumNumbers=ABMultiValueGetCount(numbers);

            for (int j=0; j<(sumNumbers>sumEmails?sumNumbers:sumEmails); j++) {
                ACL_AB_Contact *contact=[[ACL_AB_Contact alloc]initWithFirstName:firstName LastName:lastName];

                if (j<sumEmails){
                    contact.emailAddress=(NSString *)ABMultiValueCopyValueAtIndex(emails,j);
                }

                if (j<sumNumbers){
                    contact.phoneNumber=(NSString *)ABMultiValueCopyValueAtIndex(numbers,j);
                }
                [contact logContact];
                [listOfContacts addObject:contact]; 
                [contact release];
            }

        }
    }

    if(ABAddressBookHasUnsavedChanges(addressBook)){
        if(wantToSaveChanges){
            didSave = ABAddressBookSave(addressBook, &error);
            if(!didSave){
                //Error
            }
        }
        else{
            ABAddressBookRevert(addressBook);
        }
    }
    return [listOfContacts autorelease];
}
于 2012-05-08T11:37:46.860 回答
1

记录 ID 是动态的。这意味着如果您添加 2 个联系人,然后删除第一个,您将只有一个 ID 为“2”的联系人。所以我不会使用 for 语句来打通联系人。遵循通讯簿编程指南

于 2011-04-26T15:16:10.870 回答