如何将ABRecordRef添加到iPhone中的NSMutableArray?

时间:2011-05-20 11:28:51

标签: iphone objective-c xcode nsmutablearray addressbook

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

   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];
       }
   }

编译器显示此警告: 警告:传递'addObject:'的参数1'会丢弃指针目标类型的限定符 我搜索了网页,发现我必须将ABRecordRef转换为ABRecord *以便能够存储在NSMutableArray中。

[bContacts addObject:(ABRecord*) ref];

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

4 个答案:

答案 0 :(得分:12)

ABRecordRefCFTypeRef的typedef,而后者又解析为const void *。这就是警告的来源:通过调用addObject:const限定词“丢失”。

在这种情况下,我们知道没关系。 CFTypeRef是半高级类型,此类型的实例支持CFRetainCFRelease。这反过来意味着可以将它转换为id并将其视为NSObject。所以你应该能够做到:

[bContacts addObject:(id)ref];

答案 1 :(得分:7)

[bContacts addObject:(id) ref];

答案 2 :(得分: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图书馆。以下是激发此代码的代码 - &gt; url

答案 3 :(得分:4)

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

现在有两种方法可以将ABRecordRef添加到NSMutableArray,这两种方法都需要桥接演员:

直接转换

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

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

将所有权转让给ARC

[bContacts addObject:CFBridgingRelease(ref)];

这会转换ABRecordRef指针,并将其所有权转移给ARC。如果您使用过,请使用此方法。 ABPersonCreate()创建一个新人。

可以在Transitioning to ARC Release Notes中找到更多信息。 Stack Overflow上还有许多其他信息来源,例如this question