Objective-C Language
Podstawowe typy danych
Szukaj…
Składnia
- BOOL mają Pluton = TAK; // Przypisanie bezpośrednie
- BOOL fastEnough = (car.speedInMPH> = 88); // Wyrażenie porównania
- BOOL fluxCapacitorActive = (havePlutonium && fastEnough); // Wyrażenie logiczne
- id cośWicked = [witchesCupboard lastObject]; // Odzyskaj nietypowy obiekt
- identyfikator proszku = przygotujWickedIngredient (cośWicked); // Podaj i wróć
- if ([component isKindOfClass: [Toad class]]) {// Test typu wykonawczego
BOOL
Typ BOOL
jest używany dla wartości boolowskich w Objective-C. Ma dwie wartości, YES
i NO
, w przeciwieństwie do bardziej powszechnych „prawdy” i „fałszu”.
Jego zachowanie jest proste i identyczne jak w języku C.
BOOL areEqual = (1 == 1); // areEqual is YES
BOOL areNotEqual = !areEqual // areNotEqual is NO
NSCAssert(areEqual, "Mathematics is a lie"); // Assertion passes
BOOL shouldFlatterReader = YES;
if (shouldFlatterReader) {
NSLog(@"Only the very smartest programmers read this kind of material.");
}
BOOL
jest prymitywny, dlatego nie można go przechowywać bezpośrednio w kolekcji Foundation. Musi być zawinięty w numer NSNumber
. Clang zapewnia w tym celu specjalną składnię:
NSNumber * yes = @YES; // Equivalent to [NSNumber numberWithBool:YES]
NSNumber * no = @NO; // Equivalent to [NSNumber numberWithBool:NO]
Implementacja BOOL
jest oparta bezpośrednio na C, ponieważ jest typedefem standardowego bool
typu C99. Wartości YES
i NO
są zdefiniowane odpowiednio na __objc_yes
i __objc_no
. Te wartości specjalne są wbudowanymi kompilatorami wprowadzonymi przez Clanga, które są tłumaczone na (BOOL)1
i (BOOL)0
. Jeśli nie są dostępne, YES
i NO
są definiowane bezpośrednio jako rzutowana liczba całkowita. Definicje znajdują się w nagłówku środowiska wykonawczego Objective-C objc.h
ID
id
to ogólny wskaźnik obiektu, typ Objective-C reprezentujący „dowolny obiekt”. Instancja dowolnej klasy Objective-C może być przechowywana w zmiennej id
. id
i dowolny inny typ klasy można przypisywać w tę iz powrotem bez rzutowania:
id anonymousSurname = @"Doe";
NSString * surname = anonymousSurname;
id anonymousFullName = [NSString stringWithFormat:@"%@, John", surname];
Staje się to istotne podczas pobierania obiektów z kolekcji. objectAtIndex:
typy metod, takie jak objectAtIndex:
są id
właśnie z tego powodu.
DataRecord * record = [records objectAtIndex:anIndex];
Oznacza to również, że metoda lub parametr funkcji wpisany jako id
może zaakceptować dowolny obiekt.
Gdy obiekt jest wpisany jako id
, można do niego przekazać dowolny znany komunikat: metoda wysyłania nie zależy od typu czasu kompilacji.
NSString * extinctBirdMaybe =
[anonymousSurname stringByAppendingString:anonymousSurname];
Oczywiście komunikat, na który obiekt nie odpowiada, nadal spowoduje wyjątek w czasie wykonywania.
NSDate * nope = [anonymousSurname addTimeInterval:10];
// Raises "Does not respond to selector" exception
Ochrona przed wyjątkiem.
NSDate * nope;
if([anonymousSurname isKindOfClass:[NSDate class]]){
nope = [anonymousSurname addTimeInterval:10];
}
Typ id
jest zdefiniowany w objc.h
typedef struct objc_object {
Class isa;
} *id;
SEL
Selektory są używane jako identyfikatory metod w Objective-C.
W poniższym przykładzie są dwa selektory. new
i setName:
Person* customer = [Person new];
[customer setName:@"John Doe"];
Każda para nawiasów odpowiada wysłaniu wiadomości. W pierwszym wierszu wysyłamy wiadomość zawierającą new
selektor do klasy Person
aw drugim wierszu wysyłamy wiadomość zawierającą setName:
selektor i ciąg znaków. Odbiorca tych komunikatów korzysta z selektora, aby wyszukać prawidłowe działanie do wykonania.
W większości przypadków przekazywanie wiadomości przy użyciu składni nawiasów jest wystarczające, ale czasami trzeba pracować z samym selektorem. W takich przypadkach typ SEL
może być używany do przechowywania odniesienia do selektora.
Jeśli selektor jest dostępny w czasie kompilacji, możesz użyć @selector()
aby uzyskać odniesienie do niego.
SEL s = @selector(setName:);
A jeśli chcesz znaleźć selektor w czasie wykonywania, użyj NSSelectorFromString.
SEL s NSSelectorFromString(@"setName:");
Korzystając z NSSelectorFromString, pamiętaj o zawinięciu nazwy selektora w NSString.
Zwykle służy do sprawdzania, czy delegat implementuje opcjonalną metodę.
if ([self.myDelegate respondsToSelector:@selector(doSomething)]) {
[self.myDelegate doSomething];
}
IMP (wskaźnik realizacji)
IMP jest typem C odnoszącym się do implementacji metody, znanej również jako wskaźnik implementacji. Jest wskaźnikiem do początku implementacji metody.
Składnia:
id (*IMP)(id, SEL, …)
IMP jest zdefiniowany przez:
typedef id (*IMP)(id self,SEL _cmd,…);
Aby uzyskać dostęp do tej IMP, można użyć komunikatu „methodForSelector” .
Przykład 1:
IMP ImpDoSomething = [myObject methodForSelector:@selector(doSomething)];
Metodę adresowaną przez IMP można wywołać, usuwając odwołanie z IMP.
ImpDoSomething(myObject, @selector(doSomething));
Te połączenia są równe:
myImpDoSomething(myObject, @selector(doSomething));
[myObject doSomething]
[myObject performSelector:mySelector]
[myObject performSelector:@selector(doSomething)]
[myObject performSelector:NSSelectorFromString(@"doSomething")];
Przykład: 2:
SEL otherWaySelector = NSSelectorFromString(@“methodWithFirst:andSecond:andThird:");
IMP methodImplementation = [self methodForSelector:otherWaySelector];
result = methodImplementation( self,
betterWaySelector,
first,
second,
third );
NSLog(@"methodForSelector : %@", result);
Wywołujemy tutaj [NSObject methodForSelector, który zwraca nam wskaźnik do funkcji C, która faktycznie implementuje metodę, którą możemy następnie wywołać bezpośrednio.
NSInteger i NSUInteger
NSInteger to po prostu typedef dla int lub long w zależności od architektury. To samo dotyczy NSUInteger, który jest typedef dla niepodpisanych wariantów. Jeśli zaznaczysz NSInteger, zobaczysz:
#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
Różnica między int lub long ze znakiem i bez znaku polega na tym, że int lub long ze znakiem mogą zawierać wartości ujemne. Zakres int wynosi od -2 147 483 648 do 2 147 483 647, podczas gdy int bez znaku ma zakres od 0 do 4 294 967 295. Wartość jest podwojona, ponieważ pierwszy bit nie jest już używany do stwierdzenia, że wartość jest ujemna albo nie. W przypadku długiej i NSInteger na architekturze 64-bitowej zakres jest znacznie szerszy.
Większość metod dostarczanych przez Apple zwraca liczbę całkowitą NS (U) ponad normalną liczbę całkowitą. Otrzymasz ostrzeżenie, jeśli spróbujesz rzucić go na normalną int, ponieważ stracisz precyzję, jeśli korzystasz z architektury 64-bitowej. W większości przypadków nie miałoby to znaczenia, ale łatwiej jest użyć liczby całkowitej NS (U). Na przykład metoda count na tablicy zwróci wartość NSUInteger.
NSNumber *iAmNumber = @0;
NSInteger iAmSigned = [iAmNumber integerValue];
NSUInteger iAmUnsigned = [iAmNumber unsignedIntegerValue];
NSLog(@"%ld", iAmSigned); // The way to print a NSInteger.
NSLog(@"%lu", iAmUnsigned); // The way to print a NSUInteger.
Podobnie jak BOOL, liczba całkowita NS (U) jest prymitywnym typem danych, więc czasami musisz zawinąć ją w numer NSN, możesz użyć @ przed liczbą całkowitą, aby rzucić ją jak powyżej i odzyskać ją przy użyciu poniższych metod. Ale aby rzucić go na numer NSNumber, możesz również użyć następujących metod:
[NSNumber numberWithInteger:0];
[NSNumber numberWithUnsignedInteger:0];