16

Jestem nowy w rozwoju iOS i nigdy nie zajmowałem się ręcznym liczeniem odwołań (zatrzymanie, zwolnienie, autorelease). W związku z tym nie mam dobrej wiedzy na temat działania magicznego ARC.Jaki jest poprawny sposób deklarowania właściwości tylko do odczytu dla ios przy użyciu ARC

Myślałem rozumiałem, dopóki nie został zapytany, jaki rodzaj własności (weak, strong, assign, etc.) powinny być podane do właściwością tylko do odczytu, wskazując na obiekcie, takie jak:

@property (readonly,nonatomic) NSString* name; 

czytałem tutaj Questions about a readonly @property in ARC, które nie będą się kompilować, chyba że poda się zmienną stanowiącą własność; Właśnie tak stało się określenie ivar podkładową takiego:

@synthesize name = _name; 

Teraz rozumiem, że domyślna „kwalifikator życia” zmiennej jest silny, stąd: http://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011226-CH1-SW4

więc wyciąć długą historię short - pośrednio definiuję moją własność jako (readonly,nonatomic,strong), ponieważ ivar jest domyślnie zadeklarowane jako .

mam kilka pytań:

  1. Is strong poprawny kwalifikator życia w użyciu? Zakładam, że tak jest, w przeciwnym razie obiekt wspierający moje NSString* nie byłby nigdzie własnością i dlatego zostałby zwolniony automatycznie (pochodzący z ziemi Java ma to sens, ponieważ wszystkie odniesienia są domyślnie silne).

  2. Czy są jakieś inne modyfikatory mające sens w tej sytuacji, takie jak copy lub assign?

  3. Czy deklarując właściwość jako (readonly,nonatomic,strong) i (readonly,nonatomic) żadnej różnicy do kodu, który zużywa własnością? na przykład. czy deklarowanie go bez słowa kluczowego strong powoduje zapisanie wskaźnika obiektu jako __unsafe_unretained, gdzie właściwość strong byłaby przechowywana w wskaźniku?

Dzięki!

EDIT

Więc jak rozumiem teraz, obowiązuje tylko do odczytu właściwości:

  • Za niedopełnienie NSObject * typy (int, float, void *, etc) używać (readonly, assign).
  • Dla wskaźników obiektów, użyj (readonly, strong) lub (readonly, copy) - te funkcje działają tak samo dla właściwości tylko do odczytu, ale możesz chcieć semantyki kopiowania, jeśli rozszerzysz/podklasę i ponownie określisz właściwość jako readwrite.
  • Dla wskaźników obiektów, (readonly, weak) ma sens tylko wtedy, gdy zamierzasz przechowywać już słaby wskaźnik w tej właściwości (ten wskaźnik musi być silny gdzie indziej lub obiekt zostanie zwolniony).
+0

Zauważ, że "silne" zakłada się, więc jeśli przedłużyć podany tylko do odczytu '(readonly)' with '(strong)' to zadziała, ale '(copy)' nie będzie. Zamiast tego zobaczysz, że "ARC zabrania syntetyzowania usługi ... z nieokreślonym atrybutem własności lub magazynu". W tym przypadku musisz wyraźnie zaznaczyć w definicji nagłówka '(readwrite, copy)'. To wywołało mnie przez kilka minut. –

Odpowiedz

12
  1. strong jest poprawna użyć, jeśli chcesz zachować silną (posiadającą) Odniesienie do tego, co to jest, że są skierowane do. Zwykle chcesz być silny, ale w celu uniknięcia odwołań cyklicznych (szczególnie w relacjach rodzic/dziecko, gdzie jeśli rodzic wskazuje na dziecko, a dziecko wskazuje na rodzica, nigdy nie zostaną one zwolnione) czasami musisz użyć słabych odniesień . Ponadto, jeśli chcesz zachować wskaźnik do obiektu, który nie jest Twoją własnością, ale chcesz, aby był ważny tylko tak długo, jak istnieje, musisz użyć słabego wskaźnika, ponieważ gdy zostanie zwolniony przez właściciela, Twój wskaźnik automatycznie ustawi się na nil i nie wskaże pamięci, której nie powinien.

  2. assign jest używany z wartościami skalarnymi i jest domyślnym ustawiaczem. copy ma sens, jeśli chcesz automatycznie utworzyć kopię obiektu i ustawić wskaźnik na kopii zamiast wskazywać na oryginalny obiekt. Ma to sens tylko wtedy, gdy masz określoną potrzebę (zwykle dlatego, że nie chcesz, aby obiekt mutował na tobie).

  3. link, który podałeś, która pokazuje, że __strong jest domyślnym (a więc nie trzeba go określić) odnosi się do zmiennych i nie do deklarowanych właściwości. Wartością domyślną dla zadeklarowanych właściwości jest assign, co z pewnością będzie miało znaczenie. Jeśli jednak chciałeś assign, nie ma znaczenia, czy to określisz, czy nie (nie tylko po to, aby było jasne, że jest to, co chciałeś). EDIT: Jednak, jak zauważył Jacques, to się zmienia z LLVM 3.1 i domyślnie jest zmieniając z assign do strong. W takim przypadku nie ma absolutnie żadnej różnicy, czy podasz strong i możesz go pominąć, jeśli chcesz. Osobiście uważam, że dobrze jest je przeliterować (zwłaszcza, że ​​istnieje konflikt między różnymi wersjami), tak aby wszyscy patrząc na kod znajdowali się na tej samej stronie. Inni mogą się jednak nie zgadzać w tej kwestii. :)

Proponuję czytanie deklarowanych właściwościach odcinek The Objective-C Programming Language tutaj: <document removed by Apple with no direct replacement>.

+0

W rzeczywistości również zmienili domyślną dla właściwości, od następnego wydania (3.1) z Clang: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership.spelling.property –

+0

Interesujące ... Teraz to różni się między ARC i nie-ARC. Dzięki @JacquesCousteau! – lnafziger

+1

Już przeczytałem link, który podałeś wiele razy, niestety uważam, że jest to bardzo mało użyteczne, dlatego właśnie o to pytam. Jeśli chodzi o twoją odpowiedź, nie wydaje mi się, żeby dotyczyła ona mojego pytania, które odnosi się konkretnie do własności tylko do odczytu. –

7

Dodatkowy punkt: właściwości mogą zostać ponownie zadeklarowane od readonly do readwrite. Na przykład podklasa może uczynić właściwość tylko do odczytu z nadklasy odczytu-zapisu, podobnie jak liczba klas kakao posiada podklasy, które dodają zmienności. Podobnie, właściwość może być publicznie dostępna tylko do odczytu, ale klasa może redeclare go do odczytu i zapisu do użytku wewnętrznego w rozszerzeniu klasy. Tak więc, gdy klasa ustawia własną właściwość, może skorzystać z syntetyzowanego narzędzia ustawiającego, które prawidłowo zarządza pamięcią i emituje odpowiednie powiadomienia o zmianach wartości kluczowej.

W obecnej sytuacji wszystkie inne cechy nieruchomości muszą być spójne. Można sobie wyobrazić, że kompilator może rozluźnić to wymaganie. (Niektórzy uważają to za błąd.) W każdym razie, jest to jeden z powodów, dla których warto zadeklarować właściwość readonly z atrybutem własności, takim jak strong, copy, lub słabym - tak, aby pasował do redeclaracji readwrite w innym miejscu.

Co do pytania 3, czy pytasz, czy kwalifikator własności wpływa na kod wywołujący odbiorcę?Nie, nie ma.

+1

Więc silny/słaby modyfikator nie wprowadzać jakąkolwiek różnicę do właściwości readonly innej niż zmiana kwalifikatora życia syntetyzowanego ivar, czy to prawda? –

+1

Tak, to prawda. –

+0

Dziękuję bardzo za pomoc! –

0

te 2 linie kodu pracy dla mnie:

plik .h:

@property (nonatomic, readonly, copy) NSString *username; 

pliku .m:

@property (nonatomic, readwrite, copy) NSString *username; 
Powiązane problemy