Подтвердить что ты не робот

Общий тип для слабых ссылок

Я пытаюсь выяснить способ использования typeof, чтобы создать слабую ссылку на self для использования в блоках, чтобы избежать циклов сохранения.

Когда я впервые прочитал об этом, кажется, что соглашение должно было использовать __block typeof(self) bself = self;, который компилируется, но используя __block, чтобы избежать циклов сохранения, больше не работает, и вместо этого следует использовать __weak.

Однако __weak typeof(self) bself = self; приводит к ошибке:

Тип 'typeof (self)' (aka 'TUAccountsViewController * const __strong') уже имеет атрибуты retainment, установленные на нем

Есть ли способ использовать typeof или другой вызов, чтобы создать слабую ссылку на self?

4b9b3361

Ответ 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()?