how can I Add a ABRecordRef to a NSMutableArray in iPhone?

一曲冷凌霜 提交于 2019-11-29 18:21:15

问题


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?


回答1:


[bContacts addObject:(id) ref];



回答2:


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



回答3:


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




回答4:


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.



来源:https://stackoverflow.com/questions/6071256/how-can-i-add-a-abrecordref-to-a-nsmutablearray-in-iphone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!