Как я могу добавить ABRecordRef в NSMutableArray в iPhone? - PullRequest
10 голосов
/ 20 мая 2011

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

Ответы [ 4 ]

12 голосов
/ 20 мая 2011

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

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

[bContacts addObject:(id)ref];
7 голосов
/ 20 мая 2011
[bContacts addObject:(id) ref];
6 голосов
/ 20 мая 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

4 голосов
/ 24 марта 2015

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

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

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

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

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

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

[bContacts addObject:CFBridgingRelease(ref)];

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

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

...