Mamy teraz notację „kropkową” dla właściwości. Widziałem różne plecy i forths o meritum dot notacji vs. notacji wiadomości. Aby odpowiedzi były nieskalane, nie zamierzam odpowiadać w żaden sposób na pytanie.
Co myślisz o notacji kropkowej i notacji wiadomości przy dostępie do właściwości?
Spróbuj skupić się na Objective-C - moim jedynym błędem, który przedstawię, jest to, że Objective-C to Objective-C, więc twoje preferencje, aby był podobny do Java lub JavaScript, nie są prawidłowe.
Prawidłowy komentarz dotyczy kwestii technicznych (kolejność operacji, pierwszeństwo rzutowania, wydajność itp.), Przejrzystości (struktura a natura obiektu, zarówno za, jak i przeciw!), Zwięzłości itp.
Uwaga, pochodzę ze szkoły rygorystycznej jakości i czytelności kodu, pracując nad ogromnymi projektami, w których konwencja i jakość kodu są nadrzędne (zapis raz przeczytany tysiąc razy).
źródło
Odpowiedzi:
Nie używaj kropki do zachowania. Użyj kropki, aby uzyskać dostęp lub ustawić atrybut podobny do rzeczy, zazwyczaj atrybuty zadeklarowane jako właściwości.
x = foo.name; // good foo.age = 42; // good y = x.retain; // bad k.release; // compiler should warn, but some don't. Oops. v.lockFocusIfCanDraw; /// ooh... no. bad bad bad
Osobom nowym w Objective-C radziłbym nie używać kropki do niczego poza zadeklarowaną jako @właściwość. Kiedy już poczujesz język, zrób to, co uważasz za słuszne.
Na przykład uważam, że następujące rzeczy są całkowicie naturalne:
k = anArray.count; for (NSView *v in myView.subviews) { ... };
Możesz spodziewać się, że analizator statyczny clang zwiększy zdolność do sprawdzania, czy kropka jest używana tylko w przypadku niektórych wzorów, czy nie w przypadku niektórych innych wzorów.
źródło
.uppercaseString
, jak gdyby klasa mogła wyrazić swój zamiar i mieć to wymuszone przez kompilator. Być może brakuje mi czegoś, co wymaga obecnej implementacji notacji kropkowej.@property
tylko do, ale wymagałoby to od konsumenta API poznania innego logicznego wymiaru informacji, a projektanci API prawdopodobnie utopiliby się w kłótniach na temat tego, co powinno, a czego nie powinno być@property
. Zwróć uwagę, że Xcode preferuje - waży bardziej -@property
niejawne metody podczas uzupełniania kodu ... Jest to zalecane, ale nie wymuszane.@property
zadeklarowanymi metodami dostępu tylko wtedy, gdy nowy język jest nowy. Kiedy zdobędziesz pewność siebie dzięki kodowaniu w Objective-C, rób to, co uważasz za właściwe. Ciekawy; wielu z nas wróciło do bardzo ograniczonego użycia kropki.Zacznę od stwierdzenia, że zacząłem programować w Visual / Real Basic, a potem przeniosłem się na Javę, więc jestem przyzwyczajony do składni kropkowej. Jednak kiedy w końcu przeniosłem się do Objective-C i przyzwyczaiłem się do nawiasów, a potem zobaczyłem wprowadzenie Objective-C 2.0 i jego składni kropkowej, zdałem sobie sprawę, że naprawdę mi się to nie podoba. (dla innych języków jest dobrze, bo tak się toczą).
Mam trzy główne wołowiny ze składnią kropkową w Objective-C:
Wołowina nr 1: To sprawia, że nie jest jasne, dlaczego możesz otrzymywać błędy. Na przykład, jeśli mam wiersz:
something.frame.origin.x = 42;
Wtedy otrzymam błąd kompilatora, ponieważ
something
jest to obiekt i nie można użyć struktur obiektu jako lwartości wyrażenia. Jeśli jednak mam:something.frame.origin.x = 42;
Wtedy to kompiluje dobrze, bo
something
jest sama struktura, która ma człon NSRect, a ja mogę użyć jako lvalue.Gdybym adoptował ten kod, musiałbym poświęcić trochę czasu, próbując dowiedzieć się, co
something
to jest. Czy to jest struktura? Czy to przedmiot? Jednak gdy używamy składni nawiasów, jest znacznie jaśniejsza:[something setFrame:newFrame];
W tym przypadku nie ma absolutnie żadnej dwuznaczności, czy
something
jest przedmiotem, czy nie. Wprowadzenie niejednoznaczności to moja wołowina nr 1.Wołowina nr 2: W języku C składnia kropkowa jest używana do uzyskiwania dostępu do elementów struktur, a nie do wywoływania metod. Programiści mogą przesłonić metody
setFoo:
ifoo
obiektów, ale nadal mają do nich dostęp za pośrednictwemsomething.foo
. W mojej głowie, kiedy widzę wyrażenia używające składni kropkowej, spodziewam się, że będą one prostym przypisaniem do ivar. Nie zawsze tak jest. Rozważmy obiekt kontrolera, który pośredniczy w tablicy i widoku tabeli. Gdy zadzwonię , pomyślę: „Aha, metoda. Muszę zobaczyć definicję tej metody, aby upewnić się, że wiem, co ona robi”.myController.contentArray = newArray;
, spodziewałbym się, że zastąpi starą tablicę nową. Jednak pierwotny programista mógł przesłonićsetContentArray:
nie tylko ustawienie tablicy, ale także ponowne załadowanie widoku tabeli. Z linii nic nie wskazuje na to zachowanie. Gdybym miał zobaczyć[myController setContentArray:newArray];
Więc myślę, że moje podsumowanie wołowiny # 2 jest takie, że możesz zastąpić znaczenie składni kropki za pomocą niestandardowego kodu.
Wołowina nr 3: Myślę, że wygląda źle. Jako programista Objective-C jestem całkowicie przyzwyczajony do nawiązywania składni, więc czytanie i zobaczenie wierszy i wierszy pięknych nawiasów, a następnie nagłe zerwanie
foo.name = newName; foo.size = newSize;
itp. Jest dla mnie nieco rozpraszające. Zdaję sobie sprawę, że niektóre rzeczy wymagają składni kropkowej (struktury C), ale tylko wtedy ich używam.Oczywiście, jeśli piszesz kod dla siebie, użyj tego, z czym czujesz się komfortowo. Ale jeśli piszesz kod, który planujesz w ramach open source, lub piszesz coś, czego nie spodziewasz się wiecznie utrzymywać, to gorąco zachęcam do używania składni nawiasów. To oczywiście tylko moja opinia.
Najnowszy post na blogu ze składnią kropek: http://weblog.bignerdranch.com/?p=83
Obalenie powyższego postu: http://eschatologist.net/blog/?p=226 (z oryginalnym artykułem na korzyść składni kropek: http://eschatologist.net/blog/?p=160 )
źródło
something
jest to obiekt, ale natknąłem się na kilka miejsc, w których pierwotni autorzy stworzyli struktury (ze względu na szybkość, mniejsze zużycie pamięci itp.) I muszę poświęcić kilka minut, próbując dowiedzieć się, dlaczego kod nie działa t kompilować.Jestem nowym programistą Cocoa / Objective-C i moje podejście do tego jest następujące:
Trzymam się notacji do przesyłania wiadomości, mimo że zacząłem od Obj-C 2.0, i chociaż notacja kropkowa jest bardziej znajoma (moim pierwszym językiem jest Java). Powód jest dość prosty: nadal nie rozumiem dokładnie dlaczego dodali kropkę do języka. Wydaje mi się, że to niepotrzebny, „nieczysty” dodatek. Chociaż jeśli ktoś może wyjaśnić, jakie korzyści daje język, z przyjemnością to usłyszę.
Uważam jednak to za wybór stylistyczny i nie sądzę, aby był dobry lub zły sposób, o ile jest spójny i czytelny , tak jak w przypadku każdego innego wyboru stylistycznego (np. Umieszczenie otwierającego nawiasu klamrowego na tej samej linii co nagłówek metody lub następny wiersz).
źródło
Notacja z kropką Objective-C to cukier składniowy, który jest tłumaczony na normalne przekazywanie wiadomości, więc pod maską nic nie zmienia i nie robi różnicy w czasie wykonywania. Notacja kropkowa jest absolutnie nie szybsza niż przekazywanie wiadomości.
Po tej potrzebnej krótkiej preambule, zobaczyłem zalety i wady:
Zalety i wady notacji kropkowej
plusy
@property
notacji z kropką i, kompilator wykonuje dużo pracy za Ciebie, może wygenerować kod dla dobrego zarządzania pamięcią podczas pobierania i ustawiania właściwości; z tego powodu notacja kropkowa jest sugerowana przez oficjalne przewodniki samego Apple.Cons
@property
Przykłady kodu:
(1) Przykładowy kod użycia operatora złożonego:
//Use of compound operator on a property of an object anObject.var += 1; //This is not possible with standard message notation [anObject setVar:[anObject var] + 1];
źródło
Najlepszą radą jest tutaj używanie stylu języka zgodnego z samym językiem. Jednak nie jest to przypadek pisania kodu funkcjonalnego w systemie OO (lub odwrotnie), a notacja kropkowa jest częścią składni w Objective-C 2.0.
Każdy system może być nadużywany. Istnienie preprocesora we wszystkich językach opartych na C wystarczy do zrobienia naprawdę dziwnych rzeczy; wystarczy spojrzeć na konkurs zaciemnionego języka C, jeśli chcesz zobaczyć, jakie może być dziwne. Czy to oznacza, że preprocesor jest automatycznie zły i nigdy nie powinieneś go używać?
Używanie składni z kropką do uzyskiwania dostępu do właściwości, które zostały zdefiniowane jako takie w interfejsie, jest otwarte na nadużycia. Istnienie nadużycia w potencji nie musi koniecznie stanowić argumentu przeciwko temu.
Dostęp do nieruchomości może mieć skutki uboczne. Jest to ortogonalne w stosunku do składni używanej do uzyskania tej własności. CoreData, delegacja, właściwości dynamiczne (first + last = full) - wszystko to musi wykonać jakąś pracę pod okładkami. Byłoby to jednak mylące „zmienne instancji” z „właściwościami” obiektu. Nie ma powodu, dla którego właściwości musiałyby koniecznie być przechowywane w takiej postaci, w jakiej są, zwłaszcza jeśli można je obliczyć (np. Długość ciągu znaków). Więc niezależnie od tego, czy używasz foo.fullName, czy [foo fullName], nadal będzie dynamiczna ocena.
Wreszcie zachowanie właściwości (gdy jest używana jako lwartość ) jest definiowane przez sam obiekt, na przykład to, czy kopia jest pobierana, czy zachowywana. Ułatwia to późniejszą zmianę zachowania - w samej definicji właściwości - zamiast konieczności ponownego wdrażania metod. Zwiększa to elastyczność podejścia, w wyniku czego prawdopodobieństwo wystąpienia mniejszej liczby błędów (wdrożeniowych) jest mniejsze. Nadal istnieje możliwość wyboru niewłaściwej metody (tj. Kopiuj zamiast zachować), ale jest to raczej kwestia architektury niż implementacji.
Ostatecznie sprowadza się to do pytania „czy to wygląda jak struktura”. Jest to prawdopodobnie główny wyróżnik w dotychczasowych debatach; jeśli masz strukturę, działa to inaczej niż jeśli masz obiekt. Ale to zawsze była prawda; nie możesz wysłać struct wiadomości i musisz wiedzieć, czy jest oparta na stosie, czy na referencjach / malloc. Istnieją już modele myślowe, które różnią się pod względem użycia ([[CGRectocation] init] czy struct CGRect?). Nigdy nie byli zjednoczeni pod względem zachowania; musisz wiedzieć, z czym masz do czynienia w każdym przypadku. Dodanie oznaczenia właściwości dla obiektów jest bardzo mało prawdopodobne, aby zmylił programistę, który wie, jakie są ich typy danych; a jeśli nie, mają większe problemy.
Jeśli chodzi o spójność; (Cel-) C jest wewnętrznie niespójne. = jest używany zarówno do przypisania, jak i równości, na podstawie pozycji leksykalnej w kodzie źródłowym. * jest używany do wskaźników i mnożenia. BOOL są znakami, a nie bajtami (lub inną wartością całkowitą), mimo że TAK i NIE to odpowiednio 1 i 0. Spójność lub czystość nie jest tym, do czego ten język został zaprojektowany; chodziło o załatwianie spraw.
Więc jeśli nie chcesz go używać, nie używaj go. Zrób to w inny sposób. Jeśli chcesz go używać i rozumiesz, to dobrze, jeśli go używasz. Inne języki zajmują się koncepcjami ogólnych struktur danych (mapy / struktury) i typów obiektów (z właściwościami), często używają tej samej składni dla obu, pomimo faktu, że jedna jest tylko strukturą danych, a druga jest bogatym obiektem. Programiści w Objective-C powinni mieć równoważną zdolność radzenia sobie ze wszystkimi stylami programowania, nawet jeśli nie jest to twój preferowany.
źródło
Używam go do właściwości, ponieważ
for ( Person *person in group.people){ ... }
jest trochę łatwiejszy do odczytania niż
for ( Person *person in [group people]){ ... }
w drugim przypadku czytelność jest zakłócona przez przełączenie mózgu w tryb wysyłania wiadomości, podczas gdy w pierwszym przypadku jest jasne, że uzyskujesz dostęp do właściwości people obiektu grupy.
Wykorzystam go również przy modyfikowaniu kolekcji, na przykład:
jest nieco bardziej czytelny niż
W tym przypadku nacisk powinien być położony na dodawanie obiektu do tablicy zamiast łączenia w łańcuch dwóch wiadomości.
źródło
Wychowałem się głównie w erze Objective-C 2.0 i wolę notację kropkową. Dla mnie pozwala to na uproszczenie kodu, zamiast dodatkowych nawiasów, mogę po prostu użyć kropki.
Podoba mi się też składnia kropek, ponieważ naprawdę mnie to czyni czuję, że mam dostęp do właściwości obiektu, zamiast po prostu wysłać do niej wiadomość (oczywiście składnia kropkowa naprawdę przekłada się na wysyłanie wiadomości, ale ze względu na pozory , kropka wydaje się inna). Zamiast „wywoływać metodę pobierającą” przy użyciu starej składni, naprawdę wydaje się, że otrzymuję coś użytecznego bezpośrednio z obiektu.
Część debaty na ten temat dotyczy „Ale już mamy składnię kropkową i jest ona przeznaczona
structs
!”. I to prawda. Ale (i znowu, to jest tylko psychologiczne), zasadniczo czuję to samo. Dostęp do właściwości obiektu przy użyciu dot-składniowe Można poczuć taki sam, jak dostęp do elementu członkowskiego struktury, co jest mniej więcej zamierzonym efektem (moim zdaniem).**** Edycja: Jak zauważył bbum, możesz również użyć składni kropkowej do wywołania dowolnej metody na obiekcie (nie byłem tego świadomy). Więc powiem, że moja opinia na temat składni kropkowej dotyczy tylko właściwości obiektu, a nie codziennego wysyłania wiadomości **
źródło
O wiele wolę składnię wiadomości ... ale tylko dlatego, że tego się nauczyłem. Biorąc pod uwagę wiele moich zajęć w stylu Objective-C 1.0, nie chciałbym ich mieszać. Nie mam żadnego prawdziwego powodu poza „tym, do czego jestem przyzwyczajony”, by nie używać składni kropki ... Z WYJĄTKIEM to doprowadza mnie do szaleństwa
Nie wiem dlaczego, ale to naprawdę wkurza mnie bez powodu. Po prostu tak myślę
jest bardziej czytelny. Ale każdemu jego!
źródło
[self.title lowercaseString]
czy coś. Ale rozumiem stylistycznie, dlaczego mieszanie i dopasowywanie składni jest kłopotliwe. Jedynym powodem, dla którego to robię, jest wyjaśnienie, co jest właściwością, a jaka metodą, która zwraca obiekt (wiem, że właściwości to po prostu to, ale mam nadzieję, że rozumiesz, o co mi chodzi).Szczerze mówiąc, myślę, że sprowadza się to do kwestii stylu. Osobiście jestem przeciwny składni kropkowej (zwłaszcza po odkryciu, że można jej używać do wywołań metod, a nie tylko do czytania / zapisywania zmiennych). Jednakże, jeśli masz zamiar go używać, będę silny polecić nie używając go do niczego innego niż dostęp i zmianę zmiennych.
źródło
Jedną z głównych zalet programowania obiektowego jest brak bezpośredniego dostępu do stanu wewnętrznego obiektów.
Wydaje mi się, że składnia kropek jest próbą nadania jej wyglądu i wrażenia, jakby uzyskiwany był bezpośredni dostęp do stanu. Ale tak naprawdę to tylko cukier syntaktyczny nad zachowaniami -foo i -setFoo :. Ja wolę nazywać rzecz po imieniu. Składnia kropek poprawia czytelność do tego stopnia, że kod jest bardziej zwięzły, ale nie pomaga w zrozumieniu, ponieważ nie pamiętanie, że naprawdę wywołujesz -foo i -setFoo: może oznaczać kłopoty.
Wydaje mi się, że zsyntetyzowane metody dostępu są próbą ułatwienia pisania obiektów, których stan jest dostępny bezpośrednio. Uważam, że zachęca to dokładnie do takiego rodzaju projektu programu, jakiego ma unikać programowanie obiektowe.
Podsumowując, wolałbym, aby składnia kropkowa i właściwości nigdy nie zostały wprowadzone. Kiedyś byłem w stanie powiedzieć ludziom, że ObjC to kilka czystych rozszerzeń C, które bardziej przypominają Smalltalk, i nie sądzę, że to już prawda.
źródło
Moim zdaniem składnia kropkowa sprawia, że Objective-C jest mniej podobne do Smalltalk. Może to uprościć kod, ale dodaje niejednoznaczności. Jest to
struct
,union
czy obiekt?źródło
Wydaje się, że wiele osób miesza „właściwości” ze „zmiennymi instancji”. Chodzi mi o to, aby te właściwości umożliwiały modyfikowanie obiektu bez znajomości jego elementów wewnętrznych, jak sądzę. Zmienna instancji jest w większości przypadków „implementacją” właściwości (która z kolei jest „interfejsem”), ale nie zawsze: czasami właściwość nie odpowiada wartości ivar, a zamiast tego oblicza wartość zwracaną ” w locie'.
Dlatego uważam, że pomysł, że „składnia kropkowa skłania cię do myślenia, że uzyskujesz dostęp do zmiennej, jest mylący” jest błędny. Kropka lub nawias, nie powinieneś robić założeń na temat elementów wewnętrznych: to Właściwość, a nie ivar.
źródło
->
pełni tę rolę (oczywiście zawsze, gdy wspomniane ivars nie są ograniczone).Myślę, że mógłbym przełączyć się na wiadomości zamiast notacji z kropkami, ponieważ w mojej głowie object.instanceVar to po prostu instanceVar, który należy do obiektu , dla mnie nie wygląda to wcale jak wywołanie metody , a tak jest, więc może się zdarzyć on w swoim akcesorium i to, czy używasz instanceVar, czy self.instanceVar, może mieć znacznie większą różnicę niż po prostu niejawne i jawne. Tylko moje 2 ¢.
źródło
Notacja z kropką próbuje nadać wiadomościom wygląd dostępu do elementu struktury, którym nie są. W niektórych przypadkach może działać dobrze. Ale wkrótce ktoś wymyśli coś takiego:
NSView *myView = ...; myView.frame.size.width = newWidth;
Wygląda w porządku. Ale nie jest. To jest to samo co
co nie działa. Kompilator akceptuje pierwszą, ale słusznie nie drugą. I nawet jeśli wyemitował błąd lub ostrzeżenie po raz pierwszy, jest to po prostu mylące.
źródło
Nazwij mnie leniwym, ale gdybym musiał wpisać jedno „.” w porównaniu z dwoma [] za każdym razem, aby uzyskać takie same wyniki, wolałbym jeden. Nienawidzę pełnych języków. () W seplenienie doprowadzało mnie do szału. Elegancki język, taki jak matematyka, jest zwięzły i skuteczny, wszystkie inne zawodzą.
źródło
Używaj notacji z kropką (kiedy tylko możesz)
Metody instancji zwracają pewną wartość
Nie używaj notacji kropkowej
W metodach instancji zwracających void, w metodach init lub w metodzie Class.
I mój ulubiony wyjątek
NSMutableArray * array = @[].mutableCopy;
źródło
Osobiście w ogóle nie używam notacji kropkowej w kodzie. Używam go tylko w wyrażeniu powiązania CoreData KVC, gdy jest to wymagane.
Powodem, dla którego nie używam ich w kodzie, jest to, że notacja kropkowa ukrywa semantykę ustawiającą. Ustawienie właściwości w notacji z kropką zawsze wygląda jak przypisanie, niezależnie od semantyki ustawiającej (przypisz / zachowaj / kopiuj). Użycie notacji wiadomości uwidacznia, że obiekt odbierający ma kontrolę nad tym, co dzieje się w seterze i podkreśla fakt, że te efekty należy wziąć pod uwagę.
Nadal zastanawiam się, czy mógłbym chcieć użyć notacji kropkowej podczas pobierania wartości właściwości zgodnej z KVC lub zadeklarowanej, ponieważ wprawdzie jest nieco bardziej zwarta i czytelna i nie ma ukrytej semantyki. W tej chwili trzymam się notacji wiadomości dla zachowania spójności.
źródło
OK, notacja kropkowa w Objective-C wygląda naprawdę dziwnie. Ale nadal nie mogę bez niego wykonać następujących czynności:
int width = self.frame.size.width;
Działa dobrze, ale:
int height = [[[self frame] size] height];
Daje mi komunikat „Nie można przekonwertować na typ wskaźnika”. Jednak bardzo chciałbym, aby mój kod wyglądał spójnie z notacją wiadomości.
źródło
To świetne pytanie i widzę wiele różnych odpowiedzi na nie. Chociaż wielu poruszyło te tematy, spróbuję odpowiedzieć na to z innego punktu widzenia (niektórzy mogli to zrobić w sposób dorozumiany):
Jeśli używamy notacji „kropkowej”, rozdzielczość celu metody jest wykonywana w czasie kompilacji. Jeśli korzystamy z przekazywania komunikatów, rozdzielczość celu jest odroczona do wykonania w czasie wykonywania. Jeśli cele zostaną rozwiązane w czasie kompilacji, wykonanie jest szybsze, ponieważ rozwiązanie celów w czasie wykonywania obejmuje kilka kosztów ogólnych. (Nie żeby różnica czasu miała duże znaczenie). Ponieważ zdefiniowaliśmy już właściwość w interfejsie obiektu, nie ma sensu różnicowanie rozdzielczości celu dla właściwości w czasie wykonywania, a zatem notacja kropkowa jest notacją, której powinniśmy używać do uzyskiwania dostępu do właściwości.
źródło