Общий тип для слабых ссылок
Я пытаюсь выяснить способ использования typeof
, чтобы создать слабую ссылку на self
для использования в блоках, чтобы избежать циклов сохранения.
Когда я впервые прочитал об этом, кажется, что соглашение должно было использовать __block typeof(self) bself = self;
, который компилируется, но используя __block
, чтобы избежать циклов сохранения, больше не работает, и вместо этого следует использовать __weak
.
Однако __weak typeof(self) bself = self;
приводит к ошибке:
Тип 'typeof (self)' (aka 'TUAccountsViewController * const __strong') уже имеет атрибуты retainment, установленные на нем
Есть ли способ использовать typeof
или другой вызов, чтобы создать слабую ссылку на self
?
Ответы
Ответ 1
Это работает!
__typeof__(o) __weak
Что я определил в своем проекте BBlock как BBlockWeakSelf
, который можно использовать следующим образом:
BBlockWeakSelf wself = self;
https://github.com/kgn/BBlock/blob/master/BBlock.h
Отредактировано на основе ответа Aleph7.
Ответ 2
В последней версии clang Apple clang версии 4.0 (теги/Apple/clang-421.1.48) (на основе LLVM 3.1svn), то есть Xcode 4.4 +, трюк __typeof__((__typeof__(self))self)
необходимо больше. Строка __weak typeof(self) bself = self;
будет компилироваться просто отлично.
Ответ 3
Правильный способ сделать это -
__weak ActualClassName* weakSelf = self;
Макросы только не дают понять, что такое переменная на самом деле, и что вы на самом деле делаете с ней, помимо добавления нестандартного метаязыка в ваш код.
Если вам нужна более общая версия класса, чем указано в ActualClassName, вы больше не имеете дело с self
, так как там, где self
определено, также определяется класс self
.
В этих случаях вы должны использовать имя ближайшего базового класса в дереве наследования NSObject
или лучше, никогда id
, например.
__weak MyBaseClassName* weakObject = object;
Ответ 4
Справка общего типа (отсутствие необходимости импорта + фрагмент)
По моему опыту, можно использовать:
__typeof__(self) __weak weakSelf = self;
Обратите внимание, что атрибут собственности принадлежит перед фактической переменной.
Очень очевидно, что происходит, когда оно используется, и его можно превратить в удобный фрагмент кода в Xcode, который делает его еще проще в любом проекте или классе, где это необходимо. (Я использую "ws" в качестве ярлыка завершения фрагмента)
Хм.. Мне нужна слабая ссылка здесь.
ws{return}
Готово. Не нужно включать заголовок в будущих проектах для этого, просто используйте фрагмент.
Xcode Snippet
Название: Generic Weak Self Reference
Платформа: All
Язык: Objective-C
Завершение ярлыка: ws
Области завершения: Function or Method
Код: __typeof__(self) __weak weakSelf = self;
Изменить: добавлено примечание о позиции квалификатора владения на основе комментариев и информации об Xcode Snippet Info
Ответ 5
почему не просто используйте
__weak id bself = self;
Ответ 6
Я думаю, что это нормально:
__ слабый __typeof (& * self) weakSelf = self;
Ссылка на AFNetworking AFURLConnectionOperation.m.
Ответ 7
У меня была аналогичная ошибка, но я исправил ее по-другому:
Я пошел в Project Navigator → Project → Target → Build Settings
Там я искал C Language Dialect. Я изменил его с c11 на GNU99, и он решил мою проблему.
Надеюсь, это поможет:)
Ответ 8
declareBlockSafe (self), затем blk (self) внутри блока. Self может быть любой переменной или переменной экземпляра. Используйте declareBlockSafeAs для свойств и возвращаемых методов.
Также работает с не-ARC, если вы импортируете Mike Ash великолепно MAZeroingWeakRef.
https://github.com/mikeash/MAZeroingWeakRef
#if __has_feature(objc_arc)
#define declareBlockSafe(__obj__) __weak typeof(__obj__) __tmpblk##__obj__ = __obj__
#define blockSafe(__obj__) __tmpblk##__obj__
#define blk(__obj__) blockSafe(__obj__)
#define declareBlockSafeAs(__obj__, __name__) \
__weak typeof((__obj__)) __tmpblk##__name__ = (__obj__)
#else
#define declareBlockSafe(__obj__) MAZeroingWeakRef *__tmpblk##__obj__ = [MAZeroingWeakRef refWithTarget:__obj__]
#define blockSafe(__obj__) ((typeof(__obj__))__tmpblk##__obj__##.target)
#define blk(__obj__) blockSafe(__obj__)
#define declareBlockSafeAs(__obj__, __name__) \
MAZeroingWeakRef *__tmpblk##__name__ = (__obj__)
#endif
код >
Вам НЕ требуется BLK() для ARC, это просто так, что макросы могут использоваться одинаково для не-ARC.
Ответ 9
У меня есть этот макрос
#define weaken(object) __typeof__(self) __weak weakSelf = object
И я использую его как это
weaken(self);
//The block referencing weakSelf goes here
Ответ 10
Как насчет __unsafe_unretained? Это не так безопасно, как __weak, но это единственное, о чем я мог думать. Кроме того, почему вы используете typeof()?