如何在iPhone上将ABRecordRef添加到NSMutableArray中?

10

我想创建一个ABRecordRef数组来存储具有有效生日字段的联系人。

   NSMutableArray* bContacts = [[NSMutableArray alloc] init];
   ABAddressBookRef addressBook = ABAddressBookCreate();
   CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
   CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

   for( int i = 0 ; i < nPeople ; i++ )
   {
       ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i );
       NSDate* birthdayDate = (NSDate*) ABRecordCopyValue(ref, kABPersonBirthdayProperty);
       if (birthdayDate != nil){
           [bContacts addObject:ref];
       }
   }
编译器会显示这个警告: warning: passing argument 1 of 'addObject:' discards qualifiers from pointer target type 我在网上搜索后发现,我需要将ABRecordRef强制转换为ABRecord*才能存储在NSMutableArray中。
[bContacts addObject:(ABRecord*) ref];

但是似乎 ABRecord 不是 iOS 框架的一部分。现在我该如何将 ABRecordRef 存储到 NSMutableArray 中?

4个回答

12

ABRecordRef是一个CFTypeRef的typedef,而后者又解析为const void *。这就是警告来自的地方:通过调用addObject:const修饰符被“丢失”了。

在这种情况下,我们知道这是可以的。CFTypeRef是一种半高级类型,该类型的实例支持CFRetainCFRelease。这意味着将其强制转换为id并将其视为NSObject可能是可以的。因此,您应该能够简单地执行以下操作:

[bContacts addObject:(id)ref];

7
[bContacts addObject:(id) ref];

6
创建一个NSObject,用于存储ABRecordRef,如下所示:
// ABContact.h
@interface ABContact : NSObject
{
    ABRecordRef _record;
}

@property (nonatomic, readonly) NSDate *birthday;

- (id)initWithRecord:(ABRecordRef)aRecord;

@end

// ABContact.m
@implementation ABContact

#pragma mark - Init

- (id)initWithRecord:(ABRecordRef)aRecord;
{
    if ((self = [super init]))
        _record = CFRetain(aRecord);
    return self;
}


#pragma mark - Getter

- (NSDate *)birthday
{
    return (NSDate *)ABRecordCopyValue(record, kABPersonBirthdayProperty) autorelease];
}


#pragma mark - Memory management

- (void)dealloc
{
    CFRelease(_record);
    [super dealloc];
}

@end


您应该看一下iPhone食谱的作者Erica Sadum的库。这是启发此代码的代码 -> url


4

我知道这是一个老问题,但自从ARC的引入以来,处理方式已经有所不同。

现在有两种可能的方法将ABRecordRef添加到NSMutableArray中,这两种方法都需要桥接转换:

直接转换

[bContacts addObject:(__bridge id)(ref)];

这只是简单地转换了ABRecordRef指针,如果您没有使用名称中带有Create的方法自己创建ref,则应该使用它。

将所有权转移给ARC

[bContacts addObject:CFBridgingRelease(ref)];

这将转换ABRecordRef指针,并将其所有权转移给ARC。如果您使用例如ABPersonCreate()来创建新人,则应使用此选项。

有关更多信息,请参阅过渡到ARC发布说明。在Stack Overflow上还有许多其他信息丰富的来源,例如此问题


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接