как я могу добавить ABRecordRef в NSMutableArray в iPhone?

Я хочу создать массив 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];
       }
   }

Компилятор показывает это предупреждение: предупреждение: передача аргумента 1 'addObject:' отбрасывает квалификаторы из целевого типа указателя. Я поискал в Интернете и обнаружил, что мне нужно преобразовать ABRecordRef в ABRecord *, чтобы иметь возможность хранить в NSMutableArray.

[bContacts addObject:(ABRecord*) ref];

Но похоже, что ABRecord не является частью фреймворка iOS. Как теперь сохранить ABRecordRef в NSMutableArray?


person Hadi Sharghi    schedule 20.05.2011    source источник


Ответы (3)


ABRecordRef - это typedef для CFTypeRef, который, в свою очередь, преобразуется в const void *. И вот откуда приходит предупреждение: при вызове addObject: квалификатор const "теряется".

В этом случае мы знаем, что все в порядке. CFTypeRef - это тип полу-высокого уровня, экземпляры этого типа поддерживают CFRetain и CFRelease. Это, в свою очередь, означает, что можно привести его к id и рассматривать как NSObject. Итак, вы должны просто уметь:

[bContacts addObject:(id)ref];
person DarkDust    schedule 20.05.2011

Создайте 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. Вот код, который вдохновил этот код -> url

person klefevre    schedule 20.05.2011

Я знаю, что это старый вопрос, но с момента появления ARC он решается по-другому.

Есть два возможных способа добавления ABRecordRef к NSMutableArray, оба из которых требуют мостового приведения:

Прямое преобразование

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

Это просто преобразует указатель ABRecordRef, и его следует использовать, если вы не создали ref самостоятельно, используя метод, в имени которого есть Create.

Передача права собственности на ARC

[bContacts addObject:CFBridgingRelease(ref)];

Это преобразует указатель ABRecordRef и, кроме того, передает его право собственности на ARC. Это следует использовать, если вы использовали, например, ABPersonCreate(), чтобы создать нового человека.

Дополнительную информацию можно найти в Переход на ARC Примечания к выпуску. Здесь, в Stack Overflow, есть также много других информативных источников, таких как этот вопрос.

person Dennis    schedule 24.03.2015