Поиск…


Синтаксис

  • BOOL havePlutonium = YES; // Прямая привязка
  • BOOL fastEnough = (car.speedInMPH> = 88); // Выражение сравнения
  • BOOL fluxCapacitorActive = (hasPlutonium && fastEnough); // Булево выражение
  • id somethingWicked = [witchesCupboard lastObject]; // Получить нетипизированный объект
  • id powder = prepareWickedIngredient (somethingWicked); // Пропускаем и возвращаем
  • if ([component isKindOfClass: [Toad class]]) {// Тестируем тип среды выполнения

BOOL

Тип BOOL используется для логических значений в Objective-C. Он имеет два значения: YES и NO , в отличие от более обычных «истинных» и «ложных».

Его поведение прост и идентично языку 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 является примитивным, поэтому его нельзя хранить непосредственно в коллекции Foundation. Он должен быть завернут в NSNumber . Кланг предоставляет специальный синтаксис для этого:

NSNumber * yes = @YES;    // Equivalent to [NSNumber numberWithBool:YES]
NSNumber * no = @NO;    // Equivalent to [NSNumber numberWithBool:NO]

Реализация BOOL напрямую основана на C, поскольку она является типизированным стандартным типом bool типа C99. Значения YES и NO определены как __objc_yes и __objc_no , соответственно. Эти специальные значения являются встроенными компиляторами, введенными Clang, которые переведены на (BOOL)1 и (BOOL)0 . Если они недоступны, YES и NO определяются непосредственно как форма целого числа. Определения содержатся в заголовке времени Objective-C objc.h

Я бы

id - общий указатель объекта, тип Objective-C, представляющий «любой объект». Экземпляр любого класса Objective-C может быть сохранен в переменной id . id и любой другой тип класса можно назначать туда и обратно без кастинга:

id anonymousSurname = @"Doe";
NSString * surname = anonymousSurname;
id anonymousFullName = [NSString stringWithFormat:@"%@, John", surname];

Это становится актуальным при извлечении объектов из коллекции. Возвращаемые типы методов, таких как objectAtIndex: являются id именно по этой причине.

DataRecord * record = [records objectAtIndex:anIndex];  

Это также означает, что параметр метода или функции, введенный как id может принимать любой объект.

Когда объект вводится как id , любое известное сообщение может быть передано ему: отправка метода не зависит от типа времени компиляции.

NSString * extinctBirdMaybe = 
               [anonymousSurname stringByAppendingString:anonymousSurname];

Разумеется, сообщение, на которое объект фактически не отвечает, все равно вызовет исключение во время выполнения.

NSDate * nope = [anonymousSurname addTimeInterval:10];
// Raises "Does not respond to selector" exception

Защита от исключения.

NSDate * nope;
if([anonymousSurname isKindOfClass:[NSDate class]]){
    nope = [anonymousSurname addTimeInterval:10];
}

Тип id определяется в objc.h

typedef struct objc_object {
    Class isa;
} *id;

SEL

Селекторы используются как идентификаторы методов в Objective-C.

В приведенном ниже примере есть два селектора. new и setName:

Person* customer = [Person new];
[customer setName:@"John Doe"];

Каждая пара скобок соответствует отправке сообщения. В первой строке мы отправляем сообщение, содержащее new селектор, в класс Person а во второй строке мы отправляем сообщение, содержащее селектор setName: и строку. Приемник этих сообщений использует селектор для поиска правильного действия для выполнения.

В большинстве случаев достаточно передавать сообщения, используя синтаксис скобки, но иногда вам приходится работать с самим селектором. В этих случаях тип SEL может использоваться для ссылки на селектор.

Если селектор доступен во время компиляции, вы можете использовать @selector() чтобы получить ссылку на него.

SEL s = @selector(setName:);

И если вам нужно найти селектор во время выполнения, используйте NSSelectorFromString.

SEL s NSSelectorFromString(@"setName:");

При использовании NSSelectorFromString не забудьте обернуть имя селектора в NSString.

Он обычно используется для проверки того, реализует ли делегат необязательный метод.

if ([self.myDelegate respondsToSelector:@selector(doSomething)]) {
    [self.myDelegate doSomething];
}

IMP (указатель реализации)

IMP - это тип C, относящийся к реализации метода, также известный как указатель реализации. Это указатель на начало реализации метода.

Синтаксис:

id (*IMP)(id, SEL, …)

IMP определяется:

typedef id (*IMP)(id self,SEL _cmd,…);

Для доступа к этому IMP можно использовать сообщение «methodForSelector» .

Пример 1:

IMP ImpDoSomething = [myObject methodForSelector:@selector(doSomething)];

Метод, адресованный IMP, может быть вызван разыменованием IMP.

ImpDoSomething(myObject, @selector(doSomething));

Таким образом, эти призывы равны:

 myImpDoSomething(myObject, @selector(doSomething));
[myObject doSomething]
[myObject performSelector:mySelector]
[myObject performSelector:@selector(doSomething)]
[myObject performSelector:NSSelectorFromString(@"doSomething")];

Пример: 2:

SEL otherWaySelector = NSSelectorFromString(@“methodWithFirst:andSecond:andThird:");

IMP methodImplementation  = [self methodForSelector:otherWaySelector];

result = methodImplementation( self,
                          betterWaySelector,
                          first,
                          second,
                          third );

NSLog(@"methodForSelector : %@", result);

Здесь мы вызываем [NSObject methodForSelector, который возвращает нам указатель на функцию C, которая фактически реализует метод, который мы можем впоследствии вызвать напрямую.

NSInteger и NSUInteger

NSInteger - это просто typedef для int или long в зависимости от архитектуры. То же самое касается NSUInteger, который является typedef для неподписанных вариантов. Если вы проверите NSInteger, вы увидите следующее:

#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

Разница между подписанным и unsigned int или long заключается в том, что подписанный int или long может содержать отрицательные значения. Диапазон int равен -2 147 483 648 до 2 147 483 647, тогда как unsigned int имеет диапазон от 0 до 4 294 967 295. Значение удваивается, потому что первый бит больше не используется, чтобы сказать, что значение отрицательное или нет. Для длинного и NSInteger на 64-битных архитектурах диапазон намного шире.

Большинство методов, предоставляемых Apple, возвращают целое число NS (U) по нормальному int. Вы получите предупреждение, если попытаетесь применить его к нормальному int, потому что вы потеряете точность, если работаете в 64-битной архитектуре. Не то, чтобы это было важно в большинстве случаев, но проще использовать NS (U) Integer. Например, метод count в массиве вернет 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.

Подобно BOOL, NS (U) Integer является примитивным типом данных, поэтому иногда вам нужно обернуть его в NSNumber, который вы можете использовать @ перед целым, чтобы отличать его, как указано выше, и извлекать его, используя приведенные ниже методы. Но чтобы передать его NSNumber, вы также можете использовать следующие методы:

[NSNumber numberWithInteger:0];
[NSNumber numberWithUnsignedInteger:0];


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow