Ответ 1
[bContacts addObject:(id) ref];
Я хочу создать массив 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?
[bContacts addObject:(id) ref];
A ABRecordRef
является typedef для CFTypeRef
и, в свою очередь, разрешается const void *
. И здесь появляется предупреждение: при вызове addObject:
отборочный const
"потерян".
В этом случае мы это хорошо знаем. CFTypeRef - тип полувысотного уровня, экземпляры этого типа поддерживают CFRetain
и CFRelease
. Это, в свою очередь, означает, что, вероятно, ОК, чтобы передать его на id
и рассматривать его как NSObject. Поэтому вы должны просто быть в состоянии:
[bContacts addObject:(id)ref];
Создайте 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
Я знаю, что это старый вопрос, но поскольку введение ARC, это обрабатывается по-другому.
Есть два возможных способа добавления ABRecordRef
в NSMutableArray
, оба из которых требуют мостового переноса:
Прямое преобразование
[bContacts addObject:(__bridge id)(ref)];
Это просто преобразует указатель ABRecordRef
, и его следует использовать, если вы сами не создали ref
, используя метод с Create
в его имени.
Передача права собственности на ARC
[bContacts addObject:CFBridgingRelease(ref)];
Это преобразует указатель ABRecordRef
и, кроме того, переносит его право собственности на ARC. Это следует использовать, если вы использовали, например, ABPersonCreate()
, чтобы создать нового человека.
Более подробную информацию можно найти в Переход к заметкам о выпуске ARC. Здесь также есть много других источников информации о переполнении стека, например этот вопрос.