Автоматический подсчет ссылок: ошибка с быстрым перечислением
При обновлении приведенного ниже кода для использования автоматического подсчета ссылок для iOS 5 возникает ошибка, когда "state- > itemPtr" присваивается буфер при попытке выполнить Fast Enumeration, так что класс реализации может быть повторен с помощью "foreach". Ошибка, которую я получаю, - "Назначение" __autoreleasing id * 'to' __unsafe_unretained id * 'изменяет свойства сохранения/выпуска указателя ". См. Строку кода с комментарием.
/*
* @see http://cocoawithlove.com/2008/05/implementing-countbyenumeratingwithstat.html
* @see http://www.mikeash.com/pyblog/friday-qa-2010-04-16-implementing-fast-enumeration.html
*/
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state objects: (id *)buffer count: (NSUInteger)bufferSize {
NSUInteger arrayIndex = (NSUInteger)state->state;
NSUInteger arraySize = [_tuples count];
NSUInteger bufferIndex = 0;
while ((arrayIndex < arraySize) && (bufferIndex < bufferSize)) {
buffer[bufferIndex] = [_tuples objectAtIndex: arrayIndex];
arrayIndex++;
bufferIndex++;
}
state->state = (unsigned long)arrayIndex;
state->itemsPtr = buffer; // Assigning '__autoreleasing id *' to '__unsafe_unretained id*' changes retain/release properties of pointer
state->mutationsPtr = (unsigned long *)self;
return bufferIndex;
}
Переменная _tuples в этом примере является переменной экземпляра типа NSMutableArray.
Как устранить эту ошибку?
Ответы
Ответ 1
Вам нужно сменить буфер на __unsafe_unretained
:
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState *)state
objects: (id __unsafe_unretained *)buffer
count: (NSUInteger)bufferSize
источник
Изменить: простой способ избавиться от ошибки в mutationPtr
:
state->mutationsPtr = &state->extra[0];
Ответ 2
Ziminji,
У меня была та же проблема, вот как я столкнулся с этим вопросом.
Я решил это, сохранив определение параметра objects
как есть (например, сохраняя его как id *
) и вместо этого сделав двойное литье с использованием указателя void.
Итак, хотя это порождает ошибки для меня:
state->itemsPtr = (__unsafe_unretained id *)buffer // Error
Это прекрасно работало:
state->itemsPtr = (__unsafe_unretained id *)(void *)buffer // No error
Отказ от ответственности: я не эксперт по АРК, и я не могу гарантировать, что это не вызовет проблем с подсчетом ссылок. Однако, похоже, он работает правильно в моем тестировании, и он определенно компилируется без предупреждений.
Кстати, я столкнулся с этой записью в блоге с двумя частями, которая охватывает "Быстрое перечисление" в хорошем объеме:
а также эту запись в блоге __unsafe_unretained
: