在最后一次更新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())
我该如何修改此代码?
我实际上看了苹果的论坛,谷歌搜索它,Stackoverflowed它,还没有欢乐。
希望你能帮助我。
更新
使用64位接缝与此警告有关。它与我新推出的iPhone 5s相吻合。
答案 0 :(得分:20)
正如您所说,问题在于新的64位架构。 (void*)
是32位体系结构的32位指针,但是64位体系结构的64位指针。函数ABPersonGetSortOrdering()
返回类型ABPersonCompositeNameFormat
的值,该值在ABPerson.h中指定为uint32_t
。因此,警告让您知道64位指针指向32位数字。
可以通过将返回值强制转换为unsigned long
来消除警告。这是完美的,因为它在64位架构上是64位,在32位架构上是32位。
(void *)(unsigned long)ABPersonGetSortOrdering()
希望这有帮助!
答案 1 :(得分:0)
我怀疑你的问题与64位和32位架构之间的差异有关,Xcode 5.1默认启用64位支持。如果指针是64位且ints是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
实现排序方法,因为它们可能更快,当然也是更现代的做事方式。