6

上次更新到 Xcode 5.1 后,Apple 的地址簿排序示例代码停止工作。网址:https ://developer.apple.com/library/ios/documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/DirectInteraction.html

示例代码

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(
                                          kCFAllocatorDefault,
                                          CFArrayGetCount(people),
                                          people
                                  );


CFArraySortValues(
        peopleMutable,
        CFRangeMake(0, CFArrayGetCount(peopleMutable)),
        (CFComparatorFunction) ABPersonComparePeopleByName,
        (void*) ABPersonGetSortOrdering()
);

CFRelease(addressBook);
CFRelease(people);
CFRelease(peopleMutable);

但是现在,这段代码引发了一个警告

Cast to 'void *' from smaller integer type 'ABPersonSortOrdering' (aka 'unsigned int')

在这一行

(void*) ABPersonGetSortOrdering())

我应该如何修改这段代码?

实际上,我查看了 Apple 的论坛,在 Google 上搜索过,在 Stackoverflow 上搜索过,但还没有任何乐趣。

希望您能够帮助我。

更新

使用 64 位的接缝与此警告有关。它与包含我的新 iPhone 5s 不谋而合。

4

2 回答 2

20

正如您所说,问题出在新的 64 位架构上。(void*)是 32 位架构的 32 位指针,但 64 位架构的 64 位指针。该函数ABPersonGetSortOrdering()返回一个在 ABPerson.hABPersonCompositeNameFormat中指定为 a的类型的值。uint32_t所以警告是让你知道一个 64 位指针指向一个 32 位数字。

可以通过将返回值类型转换为unsigned long. 这是完美的,因为它将是 64 位架构上的 64 位和 32 位架构上的 32 位。

(void *)(unsigned long)ABPersonGetSortOrdering()

希望这可以帮助!

于 2014-03-19T21:46:12.443 回答
0

我怀疑您的问题与 64 位和 32 位架构之间的差异有关,Xcode 5.1 默认启用了 64 位支持。如果指针是 64 位而 int 是 32 位,则 int 太小而无法保存指针值。

您可以通过转到您的目标 > 构建设置来禁用您的应用程序的 64 位编译,但我强烈建议您不要这样做。此外,以下代码对我有用,它还实现了新的创建方法,并正确实现了授权检查(这确保用户已授予您的应用访问联系人的权限)

CFErrorRef * err;

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, err);

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {

    if (!granted) {
        // No Access to address book, user has denied
        return;
    }

    CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
    CFMutableArrayRef peopleMutable = CFArrayCreateMutableCopy(kCFAllocatorDefault,
                                                               CFArrayGetCount(people),
                                                               people);


    CFArraySortValues(peopleMutable,
                      CFRangeMake(0, CFArrayGetCount(peopleMutable)),
                      (CFComparatorFunction) ABPersonComparePeopleByName,
                      (void*) ABPersonGetSortOrdering());

    CFRelease(addressBook);
    CFRelease(people);
    CFRelease(peopleMutable);

});

虽然如果我真的很挑剔,我会说你应该把people数组转换成这样的 NSArray:

NSArray *people = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);

然后考虑使用它们来实现您的排序方法,NSSortDescriptors因为它们可能会更快,并且肯定是一种更现代的做事方式。

于 2014-03-17T21:26:09.750 回答