Я знаю, что OBJC_ASSOCIATION_ASSIGN существует, но делает ли он нулевую ссылку, если целевой объект освобожден? Или это похоже на старые времена, когда эта ссылка должна быть обновлена, или мы рискуем плохой доступ позже?Использование objc_setAssociatedObject со слабыми ссылками
ответ
После проверки, ответ НЕТ.
Я побежал следующий код под IOS 6 Simulator, но это, вероятно, имеют такое же поведение с предыдущей итерации выполнения:
NSObject *test1 = [NSObject new];
NSObject __weak *test2 = test1;
objc_setAssociatedObject(self, "test", test1, OBJC_ASSOCIATION_ASSIGN);
test1 = nil;
id test3 = objc_getAssociatedObject(self, "test");
В конце концов, test1 и test2 равны нулю, и test3 является указатель, ранее сохраненный в test1. Использование test3 приведет к попытке получить доступ к объекту, который уже был освобожден.
Типо там? как «test1» относится к «тесту» и «тест2»? – Jeff
Это поведение не указано в документах или заголовках, насколько я могу судить, поэтому, скорее всего, это будет деталь реализации, на которую вы не должны рассчитывать, даже если бы вы смогли определить, что такое текущее поведение. Я бы предположил, что это не обнулено. Вот почему:
В общем, нет необходимости в nil
ссылки в iVars во время -dealloc
. Если объект отменен, не имеет значения, были ли его iVars обнулены, поскольку любой последующий доступ к освобожденному объекту или его iVars сам по себе является ошибкой программирования. На самом деле, я слышал, что некоторые утверждают, что лучше не удалить ссылки во время -dealloc
, так как он сделает ошибочный доступ еще очевидным/разоблачить ошибки раньше.
EDIT: О, я думаю, я неправильно понял ваш вопрос. Вы хотите «обнулить слабые ссылки». Соответствующее хранилище, похоже, не поддерживает их. Вы можете сделать тривиальный проходной класс с одним ivar/свойством, обозначенным как __weak, и добиться такого же эффекта. Немного клодэй, но это сработает.
Я имею в виду, в случае, если я смотрю, это не ошибка, если я попытаюсь получить доступ к объекту после его освобождения. Если у меня есть слабая ссылка, как ссылка на делегата, я ожидаю, что она может не существовать к моменту моего сообщения. – ultramiraculous
Как показано на ультракрасном уровне, OBJC_ASSOCIATION_ASSIGN
не делает обнуление слабых ссылок, и вы рискуете получить доступ к освобожденному объекту. Но реализовать его очень легко. Вам просто нужно простой класс, чтобы обернуть объект со слабой ссылкой:
@interface WeakObjectContainer : NSObject
@property (nonatomic, readonly, weak) id object;
@end
@implementation WeakObjectContainer
- (instancetype) initWithObject:(id)object
{
if (!(self = [super init]))
return nil;
_object = object;
return self;
}
@end
Тогда вы должны ассоциировать WeakObjectContainer
как OBJC_ASSOCIATION_RETAIN (_NONATOMIC):
objc_setAssociatedObject(self, &MyKey, [[WeakObjectContainer alloc] initWithObject:object], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
и использовать object
свойство для доступа к нему в для того чтобы получить обнуления слабой ссылки:
id object = [objc_getAssociatedObject(self, &MyKey) object];
Хе-хе! Действительно разумный подход. Любить это! Я буду помнить об этом. – MonsieurDart
Почему бы просто не использовать NSValue :: valueWithNonretainedObject:? – AlexDenisov
Поскольку '- [NSValue nonretainedObjectValue]' не возвращает * слабый * объект и, следовательно, не делает обнуление слабым ссылкой. – 0xced
еще один вариант похож на WeakObjectContainer
:
- (id)weakObject {
id (^block)() = objc_getAssociatedObject(self, @selector(weakObject));
return (block ? block() : nil);
}
- (void)setWeakObject:(id)object {
id __weak weakObject = object;
id (^block)() = ^{ return weakObject; };
objc_setAssociatedObject(self, @selector(weakObject),
block, OBJC_ASSOCIATION_COPY);
}
- 1. Задача-C: работа со слабыми ссылками [Решено]
- 2. NSHashTable со слабыми рефрексами
- 3. Создание статических переменных со слабыми ссылками в java
- 4. ARC собственности с сильными и слабыми ссылками
- 5. Использование станд :: bind2nd со ссылками
- 6. Использование MVC3 AntiforgeryToken со ссылками?
- 7. Параллельная карта со слабыми клавишами
- 8. Использование SQLBulkCopy для нескольких таблиц со ссылками
- 9. темное отношение между потоком выполнения и слабыми ссылками?
- 10. Различия между «слабыми» и «незанятыми» ссылками в вала?
- 11. Разница между сырыми указателями и слабыми ссылками в Вала?
- 12. NSMutableDictionary со слабыми ссылками: предупреждение при использовании CFRetain в качестве обратного вызова
- 13. Смутно о сборке мусора и событиях со слабыми ссылками в actionscript 3
- 14. ConcurrentHashMap со слабыми ключами и хэш-идентификатором?
- 15. jQuery tooltip со ссылками
- 16. Textview onclicklistener со ссылками
- 17. Java работает со ссылками
- 18. Ползунок Javascript со ссылками
- 19. MySQL категории со ссылками
- 20. Частичное демаршаллинга со ссылками
- 21. Скрывающие указатели со ссылками
- 22. Динамическое выпадение со ссылками
- 23. карта winforms со ссылками.
- 24. Передача параметров со ссылками
- 25. Игра со ссылками
- 26. Редактор WYSIWYG со ссылками
- 27. AngularJS: Таблица со ссылками
- 28. css со ссылками
- 29. CSS KeyFrames со ссылками
- 30. Полиморфизм C++ со ссылками
Да, правда. Я попробую. – ultramiraculous