【问题标题】:application crashes at ABMultiValueRef应用程序在 ABMultiValueRef 处崩溃
【发布时间】:2014-11-02 10:06:27
【问题描述】:

我正在尝试访问 iPad 的地址簿电子邮件。

部分代码是:

ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
ABRecordRef recordRef = ABAddressBookCopyDefaultSource(addressBookRef);
CFArrayRef arrayRef  = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBookRef, recordRef, kABPersonSortByFirstName);

for(int i = 0;i<ABAddressBookGetPersonCount(addressBookRef);i++)
{
      ABRecordRef ref = CFArrayGetValueAtIndex(arrayRef, i);
      ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty);
      .
      .
      .
      .

崩溃只能在客户端 iPad-Mini 上重现。我们试图重现崩溃,但它没有发生。

在分析调试版本后,我们知道崩溃发生在“ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty);”行中。崩溃并非每次都发生。它在 2-3 次尝试访问地址簿电子邮件时发生一次。仅供客户使用。

我的疑问是“ABRecordRef ref = CFArrayGetValueAtIndex(arrayRef, i);”可能为 nil 或为空。但在什么情况下这可能是 nil 或空的?

谁能帮我知道崩溃的原因。

【问题讨论】:

  • 崩溃日志说什么?
  • @n00bProgrammer:抱歉,我们无法从客户端获取崩溃日志..

标签: ios iphone ipad ios7 abaddressbook


【解决方案1】:

原因可能是ABAddressBookGetPersonCount 返回通讯簿中所有人的数量,而ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering 返回只有一个来源的所有人,他们的数量可能不同。此外,我建议您检查以下错误。当然,您还必须 CFRelease 任何返回的 CF 对象。

    CFErrorRef error = nil;
    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &error);
    if (addressBookRef != nil) {
        ABRecordRef recordRef = ABAddressBookCopyDefaultSource(addressBookRef);
        CFArrayRef arrayRef  = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBookRef, recordRef, kABPersonSortByFirstName);
        const unsigned int nrAllPeopleInSource = (unsigned int)CFArrayGetCount (arrayRef);
        if (arrayRef != nil) {
//            for(int i = 0;i<ABAddressBookGetPersonCount(addressBookRef);i++)
            /*
             ABAddressBookGetPersonCount returns the number of all people in the address book, whereas
             ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering returns all people of only 1 source, and their number might be different.
             */
            for(int i = 0;i<nrAllPeopleInSource;i++)
            {
                ABRecordRef ref = CFArrayGetValueAtIndex(arrayRef, i);
                ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty);
                // ... further code
            }
        } else {
            // no person found
        }
    } else {
        // addressbook could not be opened, lookup error
    }

【讨论】:

  • 你能告诉我们在什么情况下我们可以重现崩溃?因为它没有发生在我们的设备上?或者我们怎样才能使“ABRecordRef”为零?
  • 要在您的设备上重现崩溃,向您的地址簿添加一个至少包含一个人的源就足够了。常见来源是 iCloud 或额外的 CardDAV 服务器。我猜你的默认来源是 iCloud。一个额外的 CardDAV 服务器可以是例如使用 OSX 服务器为测试目的创建。
  • 你能告诉我,如果“ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering”返回只有 1 个来源的所有人..如何让所有来源中的所有人..?
  • 您可以使用 ABAddressBookCopyArrayOfAllPeople,但您必须自己对它们进行排序。还有一件事:您还可以启用另一个 CardDAV 服务器,如果您有例如安装 Facebook 应用程序,然后将系统设置/Facebook 联系人切换到 ON。
猜你喜欢
  • 2013-09-28
  • 1970-01-01
  • 2011-09-01
  • 2020-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多