ABAddressbook 崩溃 CFStringRef

Posted

技术标签:

【中文标题】ABAddressbook 崩溃 CFStringRef【英文标题】:ABAddressbook crash CFStringRef 【发布时间】:2014-07-07 19:17:46 【问题描述】:

我有一个应用程序可以获取用户通讯录的名字和姓氏。我已经在模拟器和我自己的运行 ios 7 和 XCode 5 的 iPhone 4S 上进行了测试,它运行良好。

最近一些国际用户一直在抱怨我的应用不断在他们身上崩溃。幸运的是,我能够从 iTunes 下载崩溃日志,当我符号化它时,我发现应用程序在接下来的步骤中至少有一个用户崩溃了。我问用户他们的通讯录有什么特别之处,他提到他有一些英文名字,希伯来文。我的问题是为什么它会在那条线上崩溃? CFStringRef 是一个敏感变量,我应该使用别的东西吗?我这辈子都想不通。

崩溃日志:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x000000005152dca8
Triggered by Thread:  0

Thread 0 Crashed:
0   AppSupport 0x3237642d CPRecordGetProperty + 21
1   AppSupport 0x323765c1 CPRecordCopyProperty + 9
2   AddressBook 0x2e154457 ABRecordCopyValueUnfiltered + 79
3   AddressBook 0x2e1542f7 ABRecordCopyValue + 79
4   Contacts HD 0x0008a583 -[v1AddressBookTblController getValsForTable] (v1AddressBookTblController.m:147)

代码:

- (IBAction) getValsForTable


    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);

    ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
    CFArrayRef allPeopleArray;


    allPeopleArray = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByLastName);


    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

    //NSLog(@"Start LOOP");
    for (int i=0; i<nPeople; i++)
    
        //NSLog(@"Inside Loop %i", i);

        ABRecordRef ref = CFArrayGetValueAtIndex(allPeopleArray, i);

        //CRASH HAPPENS HERE
        CFStringRef firstNameStr = ABRecordCopyValue(ref, kABPersonFirstNameProperty); 

...

尝试在地址簿中使用非 ASCII 名字,应用仍然可以正常工作。

【问题讨论】:

线程崩溃...应用程序在这些用户上关闭。我无法在我的实际设备或模拟器上重现它 在崩溃报告中,“异常类型”显示什么?崩溃日志中还有其他有用的详细信息吗? 您在测试时尝试过各种名称组合吗?比如姓氏但没有名字,中间名但没有姓氏和名字,根本没有名字,只有电话? 是的,我创建了 3 条记录,每条记录都只有名字或姓氏或中间名。在我的 iPhone 上运行良好。异常类型为 EXC_BAD_ACCESS (SIGSEGV)。我唯一能想到的就是在其中添加一个带有国际非 ascii 字符的名称。但不知道如何在模拟器中添加那种名称。可能需要更换我的键盘 【参考方案1】:

我有同样的错误,问题是:

CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);

CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

正在提供不同数量的联系人(因此在您的情况下,nPeople 可能大于导致崩溃的allPeople)。 source 似乎没有提供通讯录中的所有联系人。将其更改为nil 为我解决了这个问题。另外,为了确保我会这样做:

nPeople = CFArrayGetCount(allPeople);

Jokinryou Tsui 在这篇文章中解释了解决方案:ABAddressBookCopyArrayOfAllPeople 和 ABAddressBookGetPersonCount return different sizes

(这是我的第一篇文章,所以我不确定我是否违反了任何规则或遵循了正确的程序。希望答案有帮助!)

【讨论】:

感谢您的建议。一百万年来,我从来没有想过会发生这种情况。让我上传一个新的二进制文件到 iTunes,一旦遇到崩溃的用户告诉我一切都很好,我会通知你

以上是关于ABAddressbook 崩溃 CFStringRef的主要内容,如果未能解决你的问题,请参考以下文章

CFString 的内存问题

ABAddressBook 没有名为“removeRecord”的成员

将 NSString 存储在 NSDIctionary 中时,变量不是 CFString

在 Zombies 工具下运行时的大型 CFString 分配,但不是泄漏或分配工具

自动化测试 ABAddressBook 和 ALAssetsLibrary 请求访问

将 ABAddressBook 中的联系人导入文本文件时出现问题