iPhone通讯录问题

时间:2011-04-26 15:07:21

标签: iphone ios exc-bad-access abaddressbook

使用通讯簿将设备中的联系人姓名输入我应用程序中的联系人视图时,我遇到了一些问题。

我在模拟器上运行的代码很好但是我在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个或更多?

3 个答案:

答案 0 :(得分:4)

只是一个猜测:

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

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

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

答案 1 :(得分:2)

以下是我如何解决它:
(注意我如何确保只调用活动记录,我也创建了一个自定义的Contact类)
这个代码处理边缘情况,如:电子邮件/电话不存在,或存在多次......

+(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];
}

答案 2 :(得分:1)

记录ID是动态的。这意味着如果您添加2个联系人然后删除第一个联系人,您将只有一个ID为“2”的联系人。因此,我不会使用for语句来通过联系人。关注Address Book Programming Guide