Niedawno próbowałem skompilować starszy projekt Xcode (który wcześniej kompilował się dobrze), a teraz widzę wiele błędów tego formularza:
error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter
Wzorzec kodu, który powoduje te błędy, zawsze wygląda następująco:
// Interface:
@property (retain) NSObject * someProperty;
// Implementation:
@synthesize someProperty; // to provide the getter
- (void)setSomeProperty:(NSObject *)newValue
{
//..
}
Rozumiem, dlaczego generowany jest błąd. Mówię kompilatorowi, aby zsyntetyzował moje metody dostępu do właściwości (zarówno pobierające, jak i ustawiające), a następnie natychmiast zastępuję metodę ustawiającą ręcznie. Ten kod zawsze trochę nieprzyjemnie pachniał.
Więc jaki jest właściwy sposób, aby to zrobić? Jeśli użyję @dynamic
zamiast @synthesize
, będę musiał również napisać getter. Czy to jedyny sposób?
atomic
nieruchomości? W przypadku właściwości atomowych dobrym pomysłem może być utrzymanie synchronizacji pary getter / setter w odniesieniu do strategii blokowania. Jest to trudne, jeśli jedna część jest syntetyzowana, a druga jest kodem niestandardowym.Odpowiedzi:
Miałem ten sam problem i po przeprowadzeniu kilku badań, oto mój wniosek dotyczący tego problemu:
Kompilator ostrzega Cię o
@property
tym, że zadeklarowałeś jako atomic (tj. Przez pominięcienonatomic
słowa kluczowego), ale podajesz niepełną implementację sposobu synchronizacji dostępu do tej właściwości.Aby to ostrzeżenie zniknęło:
Jeśli zadeklarujesz, że a
@property
jest atomowy, wykonaj jedną z następujących czynności:@dynamic
lub;@synthesize
i zachowaj syntezator setera i gettera lub;Jeśli zadeklarujesz
@property
with(nonatomic)
, możesz mieszać ręczne i syntetyzowane implementacje metod pobierających i ustawiających.Aktualizacja: uwaga na temat autosyntezy właściwości
Począwszy od LLVM 4.0, CLang zapewnia automatyczną syntezę zadeklarowanych właściwości, które nie są
@dynamic
. Domyślnie, nawet jeśli@synthesize
pominiesz opcję, kompilator zapewni Ci metody pobierające i ustawiające. Jednak zasada właściwości atomowych jest wciąż ta sama: albo niech kompilator zapewniają zarówno getter i setter, OR je realizować zarówno siebie!źródło
Musisz również zaimplementować getter. Przykład:
// Interface: @property (retain) NSObject * someProperty; // Implementation: - (void)setSomeProperty:(NSObject *)newValue { @synchronized (self) { // ... } } - (NSObject *)someProperty { NSObject *ret = nil; @synchronized (self) { ret = [[someProperty retain] autorelease]; } return ret; }
źródło
To pytanie, wśród innych najpopularniejszych wyników wyszukiwania „niestandardowej właściwości celu C”, nie jest aktualizowane o informacje o „setter =” lub „getter =”.
Tak więc, aby podać więcej informacji na to pytanie:
Możesz podać wywołanie @property z własną metodą, pisząc
@property(setter = MySetterMethod:, getter = MyGetterMethod)
Zwróć uwagę na dwukropek dla podanej metody ustawiającej.
Odniesienie dokumentacja firmy Apple
EDYCJA: Nie jestem do końca pewien, jak nowe zmiany we właściwościach Celu-C (są teraz znacznie bardziej inteligentne) zmieniają odpowiedzi na to pytanie. Być może wszystko powinno być oznaczone jako nieaktualne.
źródło
Dla innych, którzy otrzymują ten błąd nie z powodu opisanego OP, prawdopodobnie masz ten sam problem co ja:
Masz @właściwość o takiej samej nazwie jak metoda - ().
Coś takiego:
@property UIView *mainView; -(UIView *)mainView;
źródło