Objective-C Language
Grundläggande datatyper
Sök…
Syntax
- BOOL havePlutonium = JA; // Direkt anspråk
- BOOL fastEnough = (bil.speedInMPH> = 88); // Jämförelseuttryck
- BOOL fluxCapacitorActive = (harPlutonium && fastEnough); // Booleskt uttryck
- id någotWicked = [witchesCupboard lastObject]; // Hämta obypat objekt
- id-pulver = PreparWickedIngredient (någotWicked); // Gå och återvänd
- if ([ingrediensen ärKindOfClass: [padda klass]]) {// Test runtime type
BOOL
BOOL
typen används för booleska värden i Objekt-C. Det har två värden, YES
och NO
, i motsats till de vanligaste "sanna" och "falska".
Dess beteende är enkelt och identiskt med C-språket.
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.");
}
En BOOL
är en primitiv, och därför kan den inte lagras direkt i en Foundation-samling. Det måste vara inslaget i ett NSNumber
. Clang tillhandahåller speciell syntax för detta:
NSNumber * yes = @YES; // Equivalent to [NSNumber numberWithBool:YES]
NSNumber * no = @NO; // Equivalent to [NSNumber numberWithBool:NO]
Den BOOL
genomförandet direkt baserad på C: s, eftersom det är en typedef av C99 standardtyp bool
. YES
och NO
värdena definieras till __objc_yes
respektive __objc_no
. Dessa specialvärden är kompilatorbyggnader som introducerats av Clang, som översätts till (BOOL)1
och (BOOL)0
. Om de inte är tillgängliga definieras YES
och NO
direkt som cast-heltalformen. Definitionerna finns i Objekt-C runtime header objc.h
id
id
är den generiska objektpekaren, en Objekt-C-typ som representerar "valfritt objekt". En instans av alla Objekt-C-klasser kan lagras i en id
variabel. En id
och vilken som helst annan klasstyp kan tilldelas fram och tillbaka utan gjutning:
id anonymousSurname = @"Doe";
NSString * surname = anonymousSurname;
id anonymousFullName = [NSString stringWithFormat:@"%@, John", surname];
Detta blir relevant när du hämtar objekt från en samling. objectAtIndex:
av metoder som objectAtIndex:
är id
av exakt detta skäl.
DataRecord * record = [records objectAtIndex:anIndex];
Det betyder också att en metod eller funktionsparameter som är typ som id
kan acceptera alla objekt.
När ett objekt skrivs som id
kan alla kända meddelanden skickas till det: metodsändning beror inte på kompileringstiden.
NSString * extinctBirdMaybe =
[anonymousSurname stringByAppendingString:anonymousSurname];
Ett meddelande som objektet faktiskt inte svarar på kommer naturligtvis fortfarande att orsaka ett undantag vid körning.
NSDate * nope = [anonymousSurname addTimeInterval:10];
// Raises "Does not respond to selector" exception
Vaktar mot undantag.
NSDate * nope;
if([anonymousSurname isKindOfClass:[NSDate class]]){
nope = [anonymousSurname addTimeInterval:10];
}
id
typen definieras i objc.h
typedef struct objc_object {
Class isa;
} *id;
SEL
Väljare används som metodidentifierare i Objekt-C.
I exemplet nedan finns det två väljare. new
och setName:
Person* customer = [Person new];
[customer setName:@"John Doe"];
Varje par parentes motsvarar ett skickat meddelande. På den första raden skickar vi ett meddelande som innehåller den new
väljaren till klassen Person
och på den andra raden skickar vi ett meddelande som innehåller setName:
selector och en sträng. Mottagaren av dessa meddelanden använder väljaren för att leta upp rätt åtgärd att utföra.
För det mesta räcker meddelanden som passerar med hjälp av parentessyntax, men ibland måste du arbeta med själva väljaren. I dessa fall kan SEL
typen användas för att hålla en referens till väljaren.
Om väljaren är tillgänglig vid kompileringstiden kan du använda @selector()
att få en referens till den.
SEL s = @selector(setName:);
Och om du behöver hitta väljaren vid körning, använd NSSelectorFromString.
SEL s NSSelectorFromString(@"setName:");
När du använder NSSelectorFromString, se till att radera namn på väljaren i en NSString.
Det används vanligtvis för att kontrollera om en delegat implementerar en valfri metod.
if ([self.myDelegate respondsToSelector:@selector(doSomething)]) {
[self.myDelegate doSomething];
}
IMP (implementeringspekare)
IMP är en C-typ som refererar till implementeringen av en metod, även känd som en implementeringspekare. Det är en pekare till början av en metodimplementering.
Syntax:
id (*IMP)(id, SEL, …)
IMP definieras av:
typedef id (*IMP)(id self,SEL _cmd,…);
För att komma åt denna IMP kan meddelandet "methodForSelector" användas.
Exempel 1:
IMP ImpDoSomething = [myObject methodForSelector:@selector(doSomething)];
Den metod som adresseras av IMP kan kallas genom att du ställer in IMP.
ImpDoSomething(myObject, @selector(doSomething));
Så dessa samtal är lika:
myImpDoSomething(myObject, @selector(doSomething));
[myObject doSomething]
[myObject performSelector:mySelector]
[myObject performSelector:@selector(doSomething)]
[myObject performSelector:NSSelectorFromString(@"doSomething")];
Exempel: 2:
SEL otherWaySelector = NSSelectorFromString(@“methodWithFirst:andSecond:andThird:");
IMP methodImplementation = [self methodForSelector:otherWaySelector];
result = methodImplementation( self,
betterWaySelector,
first,
second,
third );
NSLog(@"methodForSelector : %@", result);
Här kallar vi [NSObject methodForSelector som ger oss en pekare till C-funktionen som faktiskt implementerar metoden, som vi sedan kan ringa direkt.
NSInteger och NSUInteger
NSInteger är bara en typedef för antingen en int eller lång beroende på arkitekturen. Detsamma gäller för ett NSUInteger som är en typef för de osignerade varianterna. Om du kontrollerar NSInteger ser du följande:
#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
Skillnaden mellan en signerad och en osignerad int eller lång är att en signerad int eller lång kan innehålla negativa värden. Intens intervall är -2 147 483 648 till 2 147 483 647 medan det osignerade intet har ett intervall från 0 till 4 294 967 295. Värdet fördubblas eftersom den första biten inte används längre för att säga att värdet är negativt eller inte. För en lång och NSInteger på 64-bitars arkitekturer är utbudet mycket bredare.
De flesta metoder som Apple tillhandahåller för att returnera ett NS (U) heltal över det normala int. Du får en varning om du försöker kasta den till ett normalt intag eftersom du kommer att förlora precision om du kör med en 64-bitars arkitektur. Inte för att det spelar någon roll i de flesta fall, men det är lättare att använda NS (U) heltal. Till exempel kommer räknemetoden på en matris att returnera ett NSUI-heltal.
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.
Precis som en BOOL är NS (U) heltal en primitiv datatyp, så du behöver ibland radera in den i ett NSNummer kan du använda @ före heltalet för att kasta det som ovan och hämta det med hjälp av metoderna nedan. Men för att kasta den till NSNumber kan du också använda följande metoder:
[NSNumber numberWithInteger:0];
[NSNumber numberWithUnsignedInteger:0];