Jestem nowy w programowaniu na Maca / iPhone'a i Objective-C. W C # i Javie mamy „generics”, klasy kolekcji, których składowe mogą być tylko zadeklarowanego typu. Na przykład w C #
Dictionary<int, MyCustomObject>
może zawierać tylko klucze będące liczbami całkowitymi i wartościami typu MyCustomObject. Czy podobny mechanizm istnieje w Objective-C?
Odpowiedzi:
W Xcode 7 firma Apple wprowadziła do Objective-C „Lightweight Generics”. W Objective-C będą generować ostrzeżenia kompilatora, jeśli wystąpi niezgodność typu.
W kodzie Swift wygenerują błąd kompilatora:
Lekkie typy generyczne są przeznaczone do użytku z NSArray, NSDictionary i NSSet, ale możesz także dodać je do swoich własnych klas:
Objective-C będzie zachowywać się tak, jak wcześniej, z ostrzeżeniami kompilatora.
ale Swift całkowicie zignoruje informacje ogólne. (Nie jest już prawdą w Swift 3+.)
Interakcja z API Objective-C
źródło
MyClass <Foo: id<Bar>>
Twój kod Swift przyjmie, że wartości są typem twojego ograniczenia, co daje ci coś do pracy. Jednak dla wyspecjalizowanych podklasMyClass
zignorowano by ich wyspecjalizowane typy (w praktyce wyglądałyby tak samo jak rodzaj ogólnyMyClass
). Zobacz github.com/bgerstle/LightweightGenericsExampleNie, w Objective-C nie ma typów ogólnych, chyba że chcesz używać szablonów C ++ we własnych klasach kolekcji niestandardowych (czego zdecydowanie odradzam).
Objective-C ma funkcję dynamicznego typowania, co oznacza, że środowisko wykonawcze nie dba o typ obiektu, ponieważ wszystkie obiekty mogą odbierać komunikaty. Po dodaniu obiektu do kolekcji wbudowanej są one traktowane tak, jakby były typem
id
. Ale nie martw się, po prostu wysyłaj wiadomości do tych obiektów jak zwykle; będzie działać dobrze (chyba że jeden lub więcej obiektów w kolekcji nie odpowie na wysyłaną wiadomość) .Typy generyczne są potrzebne w językach takich jak Java i C #, ponieważ są to silne języki z typami statycznymi. Zupełnie inna gra w piłkę niż funkcja dynamicznego pisania w Objective-C.
źródło
Nie, ale żeby było jaśniej, możesz skomentować to z typem obiektu, który chcesz przechowywać, widziałem to już kilka razy, kiedy musisz napisać coś w Javie 1.4) np:
lub
źródło
W Objective-C nie ma leków generycznych.
Z Dokumentów
źródło
Apple dodał typy generyczne do ObjC w XCode 7:
zobacz tutaj: https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/BuildingCocoaApps/WorkingWithCocoaDataTypes.html#//apple_ref/doc/uid/TP40014216-CH6-ID61
źródło
To zostało wydane w Xcode 7 (w końcu!)
Zauważ, że w kodzie Objective C jest to po prostu sprawdzenie kompilacji; nie wystąpi błąd w czasie wykonywania tylko po umieszczeniu niewłaściwego typu w kolekcji lub przypisaniu do wpisanej właściwości.
Ogłosić:
Posługiwać się:
Uważaj na te
*
s.źródło
Generyczne NSArrays można zrealizować przez podklasy
NSArray
i przedefiniowanie wszystkich dostarczonych metod na bardziej restrykcyjne. Na przykład,musiałby zostać przedefiniowany w
tak jak
aby NSArray zawierał tylko NSStrings.
Utworzona podklasa może być używana jako zamiennik typu drop-in i zapewnia wiele przydatnych funkcji: ostrzeżenia kompilatora, dostęp do właściwości, lepsze tworzenie kodu i -kompletność w Xcode. Wszystkie te funkcje są dostępne w czasie kompilacji, nie ma potrzeby ponownego definiowania rzeczywistej implementacji - nadal można używać metod NSArray.
Można to zautomatyzować i sprowadzić tylko do dwóch instrukcji, co zbliża to do języków obsługujących typy generyczne. Stworzyłem automatyzację za pomocą WMGenericCollection , w której szablony są dostarczane jako makra C Preprocessor.
Po zaimportowaniu pliku nagłówkowego zawierającego makro, można utworzyć ogólny NSArray z dwoma instrukcjami: jedną dla interfejsu i jedną dla implementacji. Musisz tylko podać typ danych, które chcesz przechowywać, i nazwy podklas. WMGenericCollection dostarcza takich szablonów
NSArray
,NSDictionary
aNSSet
, jak również ich Zmienne odpowiedniki.Przykład:
List<int>
może być zrealizowany przez niestandardową klasę o nazwieNumberArray
, która jest tworzona za pomocą następującej instrukcji:Po utworzeniu
NumberArray
możesz go używać w całym projekcie. Brakuje składni<int>
, ale możesz wybrać własny schemat nazewnictwa, aby oznaczyć je jako klasy jako szablony.źródło
Spojrzeć na:
https://github.com/tomersh/Objective-C-Generics
Wydaje się, że jest to rodzaj generycznych dla biednych ludzi, poprzez zmianę przeznaczenia mechanizmu sprawdzania protokołu.
źródło
Teraz marzenia się spełniają - od dziś w Objective-C są Generics (dzięki, WWDC). To nie jest żart - na oficjalnej stronie Swift:
I obraz, który to potwierdza:
źródło
Chcę tylko wskoczyć tutaj. Napisałem tutaj post na blogu o generykach.
Chcę wnieść swój wkład w to, że Generics można dodać do dowolnej klasy , a nie tylko do klas kolekcji, jak wskazuje Apple.
Z powodzeniem dodałem wtedy do różnych klas, ponieważ działają one dokładnie tak samo, jak kolekcje Apple. to znaczy. sprawdzanie czasu kompilacji, uzupełnianie kodu, umożliwianie usuwania rzutów itp.
Cieszyć się.
źródło
Klasy Collection dostarczane przez platformy Apple i GNUStep są półgeneryczne, ponieważ zakładają, że są to obiekty, które można sortować, a inne odpowiadają na określone wiadomości. W przypadku prymitywów, takich jak floats, ints, itp., Cała struktura tablic w języku C jest nienaruszona i może być używana, a istnieją dla nich specjalne obiekty opakowujące do użytku w ogólnych klasach kolekcji (np. NSNumber). Ponadto klasa Collection może być podzielona na podklasy (lub specjalnie zmodyfikowane za pomocą kategorii), aby akceptować obiekty dowolnego typu, ale cały kod obsługi typów musisz napisać samodzielnie. Wiadomości mogą być wysyłane do dowolnego obiektu, ale powinny zwracać wartość null, jeśli jest nieodpowiednia dla obiektu lub wiadomość powinna zostać przesłana do odpowiedniego obiektu. Błędy typu rzeczywistego powinny być wychwytywane w czasie kompilacji, a nie w czasie wykonywania. W czasie wykonywania powinny być obsługiwane lub ignorowane. Wreszcie, Objc zapewnia narzędzia do refleksji w czasie wykonywania do obsługi trudnych przypadków i odpowiedzi na wiadomość, określonego typu i usług można sprawdzić na obiekcie przed wysłaniem wiadomości lub umieszczeniem w niewłaściwej kolekcji. Uważaj, że różne biblioteki i frameworki przyjmują różne konwencje dotyczące zachowania ich obiektów podczas wysyłania wiadomości, na które nie mają odpowiedzi w kodzie, czyli RTFM. Poza programami zabawkowymi i kompilacjami do debugowania, większość programów nie powinna się zawieszać, chyba że naprawdę schrzanią i spróbują zapisać złe dane w pamięci lub na dysku, wykonać nielegalne operacje (np. Podzielić przez zero, ale to też można złapać) lub uzyskać dostęp niedostępne zasoby systemowe. Dynamika i czas wykonywania Objective-C pozwala na to, że rzeczy zawodzą z wdziękiem i powinny być wbudowane w twój kod. (WSKAZÓWKA) Jeśli masz problem z ogólnością swoich funkcji, spróbuj czegoś konkretnego. Napisz funkcje z określonymi typami i pozwól środowisku wykonawczemu wybrać (dlatego nazywa się je selektorami!) Odpowiednią funkcję składową w czasie wykonywania.
źródło