Generic typeof dla słabych odniesień do siebie

Próbuję wymyślić sposób użycia typeof, aby stworzyć słabe odniesienie do self do użycia w blokach, aby uniknąć zatrzymywania cykli.

Kiedy po raz pierwszy o tym przeczytałem, wydaje się, że konwencja miała używać __block typeof(self) bself = self;, która kompiluje, ale używanie __block, aby uniknąć zatrzymywania cykli, nie działa już i __weak powinno być używane zamiast.

Jednak __weak typeof(self) bself = self; powoduje błąd:

Typ "typeof (self)" (aka "TUAccountsViewController *const __strong") ma już atrybuty retainment set on it

Czy istnieje sposób na użycie typeof lub innego wywołania, aby ogólnie stworzyć słabe odniesienie do self?

Author: Kazuki Sakamoto, 2012-06-05

10 answers

W najnowszej wersji clang Apple clang w wersji 4.0 (tags/Apple/clang-421.1.48) (opartej na LLVM 3.1 svn) , tj. Xcode 4.4+, sztuczka __typeof__((__typeof__(self))self) nie jest już potrzebna. Linia __weak typeof(self) bself = self; będzie się dobrze skompilować.

 37
Author: 0xced,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-17 21:33:33

To działa!

__typeof__(o) __weak

Które zdefiniowałem w moim projekcie BBlock jako BBlockWeakSelf które można użyć w następujący sposób:

BBlockWeakSelf wself = self;

Https://github.com/kgn/BBlock/blob/master/BBlock.h

edytowane na podstawie odpowiedzi Aleph7.

 32
Author: keegan3d,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-28 00:16:15

Poprawnym sposobem na to jest

__weak ActualClassName* weakSelf = self;

Makra tylko sprawiają, że niejasne jest, czym jest zmienna i co faktycznie z nią robisz, oprócz dodawania przenośnego meta-języka do kodu.

Jeśli potrzebujesz bardziej ogólnej wersji klasy niż zapewnia ActualClassName, nie masz już do czynienia z self, ponieważ gdzie self jest zdefiniowana, tak samo jest zdefiniowana klasa self.

W takich przypadkach, powinieneś użyć najbliższej nazwy klasy bazowej w Twoim drzewo dziedziczenia, NSObject lub lepiej, nigdy id, np.

__weak MyBaseClassName* weakObject = object;
 18
Author: Brane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-12 15:17:21

Generic Weakself Reference (No Import Required + Snippet)


Z mojego doświadczenia wynika, że należy użyć:

__typeof__(self) __weak weakSelf = self;

Zauważ, że kwalifikator własności znajduje się przed rzeczywistą zmienną.

Jest bardzo widoczne, co się dzieje, gdy jest używany i może być wykonany w poręczny fragment kodu w Xcode, co sprawia, że jest jeszcze łatwiejszy w użyciu w każdym projekcie lub klasie, gdzie jest to potrzebne. (Używam "ws" jako dopełnienia fragmentu Skrót)

Hmm.. Potrzebuję słabego odniesienia..

ws{return}

Zrobione. Nie ma potrzeby umieszczania nagłówka w przyszłych projektach, wystarczy użyć fragmentu.


Xcode Snippet


Tytuł: Generic Weak Self Reference
Platforma: All
Język: Objective-C
Skrót Zakończenia: ws
Zakres Dopełnienia: Function or Method
Kod: __typeof__(self) __weak weakSelf = self;


Edit: Dodano notkę o pozycji kwalifikatora własności na podstawie komentarzy , oraz Xcode Snippet Info

 16
Author: Thuggish Nuggets,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:29:37

Why don ' t just use

__weak id bself = self;
 3
Author: Denis Mikhaylov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-05 06:07:21

Myślę, że użyj tego, aby było ok:

_ _ weak _ _ typeof (&*self)weakSelf = self;

Odnosi się do Afnetworking AFURLConnectionOperation.kody M.

 3
Author: kitsionchen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-22 16:51:22

Miałem podobny błąd, ale naprawiłem go inaczej:

Poszedłem do Project Navigator -> Project -> Target - > Build Settings

Tam Szukałem dialektu języka C. Zmieniłem go z c11 na GNU99 i to rozwiązało mój problem.

Mam nadzieję, że to pomoże:)

 2
Author: Ricardo Anjos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-11 17:53:19

DeclareBlockSafe (self ) następnie blk (self ) wewnątrz bloku. Self może być dowolną zmienną lub zmienną instancji. Użyj declareBlockSafeAs dla właściwości i zwrotów metod.

Działa również z nie-ARC, jeśli zaimportujesz wspaniały MAZeroingWeakRef Mike ' a Asha. 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

Tak naprawdę nie potrzebujesz blk () dla ARC, po prostu po to, aby makra mogły być używane w ten sam sposób dla nie-ARC.

 1
Author: SeruK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-17 03:06:35

Mam to makro

#define weaken(object) __typeof__(self) __weak weakSelf = object

I używam go tak

weaken(self);
//The block referencing weakSelf goes here
 1
Author: Maciej Swic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-12 09:20:06

A co z _ _ unsafe _ unreated? To nie jest tak bezpieczne jak _ _ słabe, ale to jedyna rzecz, o której mogłem myśleć. Dlaczego używasz metody typeof ()?

 0
Author: lbrndnr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-05 10:56:35