Różnica między sobą. w Objective-C

Czy jest różnica między używaniem podkreślnika a używaniem self słowa kluczowego w Objective-C podczas wywoływania @property?

Oświadczenie majątkowe:

@property (weak, nonatomic) NSString *myString;

Wywołanie @synthesize w obiekcie:

@synthesize myString = _myString;

Czy jest różnica, czy chcę użyć go w moim kodzie? Kiedy? W getter/setter?

self.myString = @"test";
_myString = @"test";
Author: Josue Espinosa, 2012-04-26

4 answers

self.myString = @"test"; jest dokładnie równoznaczne z zapisem [self setMyString:@"test"];. Oba wywołują metodę.

Mogłeś sam napisać tę metodę. Może to wyglądać mniej więcej tak:
- (void)setMyString:(NSString*)newString
{
    _myString = newString;
}

Ponieważ użyłeś @synthesize, nie musisz się trudzić pisaniem tej metody, możesz po prostu pozwolić kompilatorowi napisać ją za Ciebie.

Patrząc na tę metodę, wygląda na to, że jej wywołanie zrobi dokładnie to samo, co przypisanie wartości do zmiennej instancji, prawda? Cóż, to to nie takie proste.

Po pierwsze, możesz napisać własną metodę setera. Jeśli to zrobisz, Twoja metoda zostanie wywołana i może wykonywać różne dodatkowe rzeczy, a także ustawiać zmienną. W takim przypadku użycie self.myString = wywoła Twoją metodę, ale wykonanie _myString = nie wywoła, a tym samym użyta byłaby inna funkcjonalność.

Po drugie, jeśli kiedykolwiek użyjesz obserwacji wartości klucza, kompilator zrobi kilka bardzo sprytnych sztuczek. Za kulisami, podklasa Twoją klasę i nadpisuje twojego setera metoda (niezależnie od tego, czy jest to ta, którą sam napisałeś, czy generowana przez syntezę), w celu wykonania wywołań do willChangeValueForKey:, które są potrzebne do działania obserwacji wartości klucza. Nie musisz wiedzieć, jak to działa (chociaż jest to dość interesujące, jeśli chcesz poczytać na dobranoc!), ale musisz wiedzieć, że jeśli chcesz, aby obserwacja wartości klucza działała automatycznie, musisz użyć metod settera.

Po Trzecie, wywołanie metody setter nawet jeśli polegasz na synthesize do napisania jednej daje elastyczność na przyszłość. Możesz chcieć zrobić coś dodatkowego za każdym razem, gdy wartość zostanie zmieniona, a w momencie, gdy odkryjesz, że chcesz to zrobić, możesz ręcznie napisać metodę settera - jeśli masz w zwyczaju zawsze używać self.myString =, nie będziesz musiał zmieniać reszty kodu, aby rozpocząć wywoływanie nowej metody!

Po czwarte, to samo dotyczy podklas. Jeśli ktoś inny podklasuje Twój kod, jeśli użyjesz setterów, to może je nadpisać, aby dostosować funkcjonalność.

Za każdym razem, gdy uzyskujesz bezpośredni dostęp do zmiennej instancji, wyraźnie nie zapewniasz możliwości podłączenia dodatkowej funkcjonalności w tym momencie. Ponieważ ty lub ktoś inny może chcieć podłączyć taką funkcjonalność w przyszłości, opłaca się używać seterów cały czas, chyba że jest dobry powód, aby tego nie robić.

 72
Author: Amy Worrall,
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-04-26 12:49:01

Masz rację-pierwsza wersja (self.myString) wywołuje zsyntetyzowany getter / setter, a druga wersja ma bezpośredni dostęp do prywatnej zmiennej członkowskiej.

Wygląda na to, że używasz ARC, więc w tym przypadku nie robi to wielkiej różnicy. Jeśli jednak nie używasz ARC, może to mieć znaczenie, ponieważ przypisanie bezpośrednio do członka prywatnego nie spowoduje automatycznego zachowania / wydania lub kopiowania / wydania logiki, która jest generowana dla ciebie za pomocą synthesize.

 9
Author: Eric Petroelje,
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-04-26 12:37:48

_ (podkreślenie) jest po prostu konwencją, jak wyjaśniono wto pytanie .

Gdy nie poprzedzasz właściwości access przez self., uzyskujesz bezpośredni dostęp do zmiennej bazowej, tak jak w c struct. Ogólnie rzecz biorąc, powinieneś to robić tylko w swoich metodach init i w niestandardowych accesorach właściwości. To pozwala rzeczy takie jak właściwości obliczeniowe i KVC działać zgodnie z przeznaczeniem.

 3
Author: Gil,
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 11:47:23

Jest wskazówka nie wspominając, dostęp za pomocą podkreślenia jest szybszy, a dostęp za pomocą self jest bezpieczniejszy (KVC). Może to podsumuje, kiedy musisz użyć każdego z nich.

 0
Author: JFCa,
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
2018-08-07 08:13:19