2013-03-13 35 views
10

Jaki powinien być najlepszy sposób w aplikacji na iOS, aby zapobiec zmianie zmiennej instancji przez obiekt, gdy inny z nich korzysta? Czy powinno być wystarczające zastosowanie dyrektywy @synchronized(self)?Blokowanie zmiennej instancji w Objective-C

góry dzięki

+0

to jest instancja var, a nie klasa var .. i nikt nie może powiedzieć ci rzetelnie podając tylko tę małą informację –

+0

Czy to naprawdę dobry pomysł, aby edytować pytanie ("zmienna klasy" -> "instancja zmiennej"), jeśli jeden * myśli * to właśnie oznaczało PO? Odczytując poprzednie pytanie i odpowiedź, mogło to oznaczać, że miał na myśli "zmienną klasy". –

+0

Przepraszam, moja wina, powiedziałbym "zmienną statyczną", jest to flaga, której wartość muszę udostępnić wszystkim instancjom klasy i upewnić się, że może ona zostać zmieniona tylko przez instancję w określonym czasie – AppsDev

Odpowiedz

1

Jeśli jedynym celem jest, aby być w stanie uzyskać dostęp

self.myString; //getter 

oraz,

self.myString=aString; //setter 

Najlepszym sposobem jest zadeklarować ją jako pierwiastka, na przykład:

@property (atomic, strong) NSString* myString; 

Zapewni to, że w środowisku wielowątkowym, ustawienie i pobieranie myString przez wątek 1 jest chronione przed wątkiem 2, który robi coś z nim.

+8

atomic! = thread safe – justin

+0

Justin, pozwól mi zaktualizować moją odpowiedź, aby była jaśniejsza. – Spectravideo328

5

Jeśli chcesz, aby obiekt był blokowany, aby żadne dwa wątki nie używały go w tym samym czasie, to synchronizacja @ jest jednym ze sposobów. But this does not make it thread-safe.

Można również użyć GCD(Grand Central Dispatch) dla tego samego

+1

Założono, że '@ synchronize' (lub jeden z innych miriadnych mechanizmów synchronizacji) został użyty właśnie w celu uczynienia go bezpiecznym dla wątków. Prawdą jest, że jeśli zrobisz to źle, to nie zadziała. I, tak, istnieją lepsze sposoby na uzyskanie bezpiecznego dla wątków kodu (a la [Tips for Thread Safety] (https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html # // apple_ref/doc/uid/10000057i-CH8-SW6)). Niezależnie od tego, czy możesz wyjaśnić, że '@ synchronize' nie sprawia, że ​​wątek jest bezpieczny? Myślałem, że to był cały cel technik synchronizacji. – Rob

+0

@Rob: W końcu znajduję to tutaj. Nauczyłem się tego również w wywiadzie: p –

+1

Och, brakowało mi wklejenia: p http://stackoverflow.com/questions/10853529/locking-an-object-from-being-accessed-by-multiple-threads-objective-c –

4

Jaki powinien być najlepszym sposobem w aplikacji iOS aby zapobiec instancję zmiennej przed zmianą przez przedmiot, podczas gdy inny używa go?

Dobra stara blokada, taka jak pthread_mutex; można również użyć tego typu wrappera Objective-C (np. NSLock i NSRecursiveLock). @synchronized również należy do tej kategorii, ale jest to mechanizm najwyższego poziomu wspomniany tutaj.

Oczywiście lepsze rozwiązania współbieżne zwykle mają więcej wspólnego ze zmianami w projekcie, przepływem programu, faworyzowaniem niezmienności i tak dalej. Wciąż będą przypadki, w których wzajemne wykluczenie/blokowanie jest preferowane lub wymagane.

Niestety, czysty ObjC/kakao jest bardzo mało w tej dziedzinie - opracowanie wysoce wydajnego równoległego programu przy użyciu technologii ObjC i kakao jest znacznie trudniejsze niż powinno być (lub musi być).

Czy użycie dyrektywy @synchronized (self) powinno być wystarczające?

Dla prostych przypadków jest wystarczająca. Jest to poziom obiektu Blokada rekursywna.

Jest jednak dość powolny w porównaniu z innymi opcjami wzajemnego wykluczania.

Nie sądzę @synchronized ma wiele dzieje się za nim, oprócz:

  • wygody dla deweloper wprowadzenie (może mieć złe skutki uboczne) i
  • symetria (to zapewnia mecze odblokowujące blokada), znacznie zmniejszając prawdopodobieństwo zakleszczenia w porównaniu do alternatyw (bardzo dobry atrybut).

@synchronized jest wygodne, ale dlatego, że ma wysokie koszty, należy stosować rozważnie.