2012-04-09 8 views
7

Rozważmy:skopiować właściwość i Block_copy (myBlock)/[myBlock kopia]

typedef void (^select_block_t)(UIView *) ; 

(1) @property (copy, nonatomic) select_block_t  myBlockProperty ; 
(2) @property (strong, nonatomic) select_block_t  myBlockProperty ; 
(3) @property (assign, nonatomic) select_block_t  myBlockProperty ; 

oraz:

(A) self.myBlockProperty = ^(UIView *) {NSLog(@"Hi");} ; 
(B) self.myBlockProperty = [^(UIView *) {NSLog(@"Hi");} copy] ; 

Próbuję zrozumieć, co jest poprawny sposób mapę, która deklarację mienia, z którym blok kopii semantyka

I przykładowe here na S.O. które sprzyjają [1: B]

Ale potem jestem zdezorientowany tym, jak niepotrzebna jest operacja "kopiowania". Moje ograniczone zrozumienie polega na tym, że [1: A] powinno być poprawne, ponieważ chcę, aby jeden blok był kopiowany raz, gdy przypiszę właściwość, a nie raz przy tworzeniu bloku, a następnie raz jeszcze w czasie przypisywania własności.

[3: B] również miałoby sens zgodnie z moimi przesłankami. Więc, co ja nie rozumiem?

Odpowiedz

9

[1: A] jest poprawny, tak. [3: B] jest nieprawidłowe, ponieważ:

  1. nie jest jasne, że klasa jest właścicielem nieruchomości, dlatego należy zwolnić go w dealloc (ale powinno)
  2. setter (B) wygląda wycieku, a Analizator statyczny może oznaczyć go jako taki, ponieważ blok jest kopiowany, przekazywany do właściwości, a następnie opuszcza zakres z zachowaniem liczby +1.
  3. użycie (3) oznacza, że ​​działa tylko wtedy, gdy ustawiłeś blok-stertę (kopiowany blok) z zachowaną liczbą równą jeden. Pozostawia to duży margines błędu przy korzystaniu z nieruchomości. (1) działa zarówno z blokami stosu, jak i blokami sterty, a także poprawnie zachowuje automatycznie zwalniane bloki.

EDYCJA: Widzę, że używasz ARC. W takim przypadku nie można w ogóle użyć [3: B]. Kompilator zwolni obiekt (nawet jeśli jest on poza zakresem), a to ustawienie właściwości nie zachowa go. Dlatego właściwość będzie zawierała zły wskaźnik, to EXC_BAD_ACCESS, czekając na zdarzenie.

+0

Czekaj, zobaczyłeś swój tag _automatic-ref-counting_, używasz ARC? – joerick

+0

Tak, używam ARC. – verec

+0

@verec Zaktualizowałem swoją odpowiedź. Daj mi znać, jeśli masz jakieś pytania, nie jestem pewien, jaki byłem jasny! – joerick