how can I Add a ABRecordRef to a NSMutableArray in

2019-02-09 03:10发布

I want to create an array of ABRecordRef(s) to store contacts which have a valid birthday field.

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

The compiler shows this warning: warning: passing argument 1 of 'addObject:' discards qualifiers from pointer target type I searched the web and found I have to cast ABRecordRef to a ABRecord* to be able to store in a NSMutableArray.

[bContacts addObject:(ABRecord*) ref];

But it seems ABRecord is not part of iOS frameworks. Now how I store ABRecordRef to NSMutableArray?

4条回答
叛逆
2楼-- · 2019-02-09 03:48

Create an NSObject wich store your ABRecordRef like this :

// 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


You should take a look at the Erica Sadum library the author of the iPhone cookbook. Here is the code wich inspire this code -> url

查看更多
你好瞎i
3楼-- · 2019-02-09 03:52
[bContacts addObject:(id) ref];
查看更多
我想做一个坏孩纸
4楼-- · 2019-02-09 03:52

I know this is an old question, but since the introduction of ARC, this is handled in a different way.

There are two possible ways of adding an ABRecordRef to an NSMutableArray now, both of which require a bridged cast:

Direct conversion

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

This simply converts the ABRecordRef pointer, and should be used, if you didn't create ref yourself using a method that has Create in its name.

Transfer ownership to ARC

[bContacts addObject:CFBridgingRelease(ref)];

This converts the ABRecordRef pointer, and in addition transfers its ownership to ARC. This should be used, if you used e.g. ABPersonCreate() to create a new person.

More information can be found in the Transitioning to ARC Release Notes. There are also many other informative sources here on Stack Overflow, such as this question.

查看更多
迷人小祖宗
5楼-- · 2019-02-09 04:06

A ABRecordRef is a typedef for CFTypeRef and that in turn resolves to const void *. And this is where the warning comes from: with the call to addObject:, the const qualifier is "lost".

In this case we know it's OK. A CFTypeRef is a semi-highlevel type, instances of this type support CFRetain and CFRelease. That in turn means it's probably OK to cast it to id and treat it as a NSObject. So you should be simply able to do:

[bContacts addObject:(id)ref];
查看更多
登录 后发表回答