Полный список директив компилятора Objective-C 2.0
Очень сложно найти полный список директив компилятора Objective-C в одном месте. Всем конечно известны @interface, @implementation, но есть и такие, как @dynamic и @encode которые встречают гораздо реже, и зачастую понимаются неправильно.
Вот их полный список, разъяснения приводятся под катом:
Используется для предварительного объявления класса. При использовании этой директивы класс помечается как известный, даже без загрузки заголовочного файла.
Однако, в отличии от @protocol и @selector вы не можете написать следующее для получения класса по имени
используйте вместо этого
Директивы используются для объявления протокола. Кроме того, протокол может адаптировать другие протоколы.
Также как и в случае с @selector вы можете использовать @protocol для получения объекта по имени:
Зависимые директивы
@interface — определяет начало объявления класса или категории.
Объявление класса
Класс предок может не объявляться, однако, все классы Objective-C должны напрямую или косвенно наследоваться от NSObject. Директива @interface может определять также, что класс адаптирует определенные протоколы:
Объявление категории
Директива @interface для категорий не может добавлять переменных экземпляра. Однако, она может определять, что категория адаптирует дополнительные протоколы. Имя категории может быть опущено (остаются только круглые скобки), если категория добавляется в файл реализации для добавления частных методов класса.
Зависимые директивы
Директива @implementation определяет начало определения (реализации) класса или категории.
Определение класса
Определение категории
Зависимые директивы
Директивы используются для обработки исключений
Посылка и обработка исключений
Заключает блок кода в мьютекс. Обеспечивает гарантию того, что блок кода и объект блокировки будут доступны только из одного потока в момент времени.
В тех приложения, в которых вы используете автоматический подсчет ссылок (ARC), вы должны использовать @autoreleasepool как замену для NSAutoreleasePool. И вообще, @autoreleasepool примерно в 6 раз быстрее, чем NSAutoreleasePool, поэтому Apple рекомендует использовать его даже для не-ARC приложений.
Кроме того, вы не должны определять переменную внутри блока @autoreleasepool и затем продолжать использовать ее после. Подобный код должен быть исключен.
Пример использования:
Возвращает специальный тип селекторов SEL выбранного метода Objective-C. Генерирует предупреждение компилятора, если метода не объявлен или не существует.
Возвращает кодировку типа.
Позволяет вам задать псевдоним для существующего класса. Первый параметр — имя псевдонима для имени класса, класса с таким именем не должно существовать. Второй параметр — имя существующего класса, для которого создается псевдоним.
После этого, вы можете использовать AliasClassName вместо ExistingClassName. Это может быть полезно после переименования класса без изменения его поведения. Вы можете использовать @compatibility_alias для того, чтобы не делать много изменений в существующем коде.
Объявляет константный объект класса NSString. Для таких строк не требуется вызывать retain или release.
Я надеюсь, что вам понравился этот список, и он будет полезен вам. Если есть какие-то директивы, которых нет в списке, пожалуйста опишите их в комментариях к статье. Буду очень благодарен.
По мотивам тут.
Вот их полный список, разъяснения приводятся под катом:
- @class
- @protocol @required @optional @end
- @interface @public @package @protected @private @property @end
- @implementation @synthesize @dynamic @end
- @throw @try @catch @finally
- @synchronized @autoreleasepool
- @selector @encode
- @compatibility_alias
- @«string»
@class
Используется для предварительного объявления класса. При использовании этой директивы класс помечается как известный, даже без загрузки заголовочного файла.
@class ClassName
Однако, в отличии от @protocol и @selector вы не можете написать следующее для получения класса по имени
// ОШИБКА: это работать не будет!
Class c = @class( ClassName );
используйте вместо этого
Class c = [ ClassName class ];
@protocol @required @optional @end
Директивы используются для объявления протокола. Кроме того, протокол может адаптировать другие протоколы.
@protocol ProtocolName < aProtocol, anotherProtocol >
@required
// объявление сообщений
@optional
// объявление сообщений
@end
Также как и в случае с @selector вы можете использовать @protocol для получения объекта по имени:
-( void ) aMethod
{
Protocol* aProtocol = @protocol( ProtocolName );
}
Зависимые директивы
- @requred (используется по-умолчанию) — Определяет методы, которые следуют после @required как обязательные.
- @optional — Определяет методы, которые следуют после @optional как необязательные. Классы, которые адаптируют протокол, могут сами решать — реализовывать эти методы или нет. Классы, которые используют необязательные методы протокола, должны делать проверку на существование. Например:
[ object respondsToSelector: @selector( optionalProtocolMethod ) ];
- @end — определяет завершение объявления протокола
@interface @public @package @protected @private @property @end
@interface — определяет начало объявления класса или категории.
Объявление класса
Класс предок может не объявляться, однако, все классы Objective-C должны напрямую или косвенно наследоваться от NSObject. Директива @interface может определять также, что класс адаптирует определенные протоколы:
@interface ClassName : SuperClassName < aProtocol, anotherProtocol >
{
@public
// переменные экземпляра
@package
// переменные экземпляра
@protected
// переменные экземпляра
@private
// переменные экземпляра
}
// объявление свойств
@property ( atomic, readwrite, assign ) id aProperty;
// публичные методы класса и экземпляров
@end
Объявление категории
Директива @interface для категорий не может добавлять переменных экземпляра. Однако, она может определять, что категория адаптирует дополнительные протоколы. Имя категории может быть опущено (остаются только круглые скобки), если категория добавляется в файл реализации для добавления частных методов класса.
@interface ClassName ( CategoryName ) < aProtocol, anotherProtocol >
// объявление свойств
@property ( nonatomic, retain ) NSString* stringProperty;
// объявление методов
@end
Зависимые директивы
- @public — Определяет, что переменные экземпляра, следующие за директивой будут доступны публично. Публичные переменные могут быть прочтены и изменены с помощью следующей конструкции:
someObject->aPublicVariable = 10;
- @package — Определяет, что переменные экземпляра, следующие за директивой будут публично доступны в библиотеке, которая определяет класс, но закрытыми за пределами этой библиотеки. Важное замечание, это справедливо только для 64-разрядных систем. На 32-разрядных системах имеет то же значение, что и @public
- @protected (по умолчанию) — Определяет, что переменные экземпляра, следующие за директивой, будут доступны только для класса и его потомков.
- @private — Определяет, что переменные экземпляра, следующие за директивой, будут доступны только в пределах данного класса
- @property — Определяет свойство, которое может быть использовано с помощью точечной нотации. За директивой @property могут следовать необязательные круглые скобки, которые содержат дополнительные ключевые слова, которые определяют поведение свойства. Вот они:
- readwrite (по-умолчанию) и readonly — генерируются одновременно сеттеры и геттеры (setters/getters) или только геттеры
- assign (по-умолчанию) и retain, copy — применяются только для свойств, которые могут быть безопасно приведены к id. Assign — просто присваивает переданное значение. Retain — посылает release текущему значению переменной экземпляра, потом посылает retain новому объекту, и присваивает новое значение переменной экземпляра. Copy — посылает release текущему значению переменной экземпляра, затем copy новому объекту и присваивает новый объект переменной экземпляра. В последних двух случаях, вы должны послать release (или присвоить nil) свойству при dealloc.
- atomic, (по-умолчанию) и nonatomic — свойства с ключевым словом atmoic — потокобезопасны, с nonatomic — могут быть проблемы при многопоточном доступе. Доступ к nonatomic свойствам обычно быстрее чем к atomic, поэтому они часто используются в однопоточных приложениях.
- weak (по-умолчанию) и strong — доступны, если включен автоматический подсчет ссылок (Automatic Reference Counting — ARC). В этом случае strong — это синоним для retain, в то время как weak — assign, с одним лишь исключением, что свойство с weak автоматически устанавливается в nil когда объект уничтожается. Также следует учитывать, что ключ weak доступен только начиная с iOS 5 и Mac OS X 10.7 (Lion).
- @end — Определяет завершение объявления класса или категории
@implementation @synthesize @dynamic @end
Директива @implementation определяет начало определения (реализации) класса или категории.
Определение класса
@implementation ClassName
@synthesize aProperty, bProperty;
@synthesize cProperty=instanceVariableName;
@dynamic anotherProperty;
// определение методов
@end
Определение категории
@implementation ClassName ( CategoryName )
@synthesize aProperty, bProperty;
@synthesize cProperty=instanceVariableName;
@dynamic anotherProperty, bnotherProperty;
// определение методов
@end
Зависимые директивы
- @synthesize — дает указание компилятору, что необходимо автоматически сгенерировать сеттеры и геттеры для данных (разделенных запятой) свойств. Сеттеры и геттеры автоматически создаются согласно указанным в объявлении свойства директивам. Если переменные экземпляра называются не так, как указано после директивы @property, вы можете соединить их с помощью знака равенства
- @dynamic — сообщает компилятору, что требуемые сеттеры и геттеры для данных свойств будут реализованы вручную или динамически во время выполнения. При доступе к таким свойствам, компилятор не будет выдавать предупреждений, даже если требуемые сеттеры и геттеры не реализованы. Вы можете использовать такие свойства, когда хотите, чтобы сеттеры и геттеры выполняли какой-то специфичный для вас код.
- @end — указывает на завершение определения класса или категории
@throw @try @catch @finally
Директивы используются для обработки исключений
Посылка и обработка исключений
@try
{
// код, который может кинуть исключение ... как например
NSException* exception =
[ NSException exceptionWithName: @"ExampleException"
reason: @"In your face!"
userInfo: nil ];
@throw exception;
}
@catch ( CustomException* ce )
{
// код обработки определенного исключения
}
@catch ( NSException* ne )
{
// код обработки всех остальных исключений
// чтобы просто пробросить исключение дальше
@throw ;
}
@finally
{
// код, который выполнится всегда после обработки, несмотря на то
// было исключение или нет
}
@synchronized
Заключает блок кода в мьютекс. Обеспечивает гарантию того, что блок кода и объект блокировки будут доступны только из одного потока в момент времени.
-( void ) aMethodWithObject: ( id )object
{
@synchronized( object )
{
// код, который работает с объектом блокировки
}
}
@autoreleasepool
В тех приложения, в которых вы используете автоматический подсчет ссылок (ARC), вы должны использовать @autoreleasepool как замену для NSAutoreleasePool. И вообще, @autoreleasepool примерно в 6 раз быстрее, чем NSAutoreleasePool, поэтому Apple рекомендует использовать его даже для не-ARC приложений.
Кроме того, вы не должны определять переменную внутри блока @autoreleasepool и затем продолжать использовать ее после. Подобный код должен быть исключен.
Пример использования:
-( void ) aMethod
{
@autoreleasepool
{
// код, который создает большое количество временных объектов
}
}
@selector
Возвращает специальный тип селекторов SEL выбранного метода Objective-C. Генерирует предупреждение компилятора, если метода не объявлен или не существует.
-( void ) aMethod
{
SEL aMethodSelector = @selector( aMethod );
[ self performSelector: aMethodSelector ];
}
@encode
Возвращает кодировку типа.
-( void ) aMethod
{
char* enc1 = @encode( int ); // enc1 = "i"
char* enc2 = @encode( id ); // enc2 = "@"
char* enc3 = @encode( @selector( aMethod ) ); // enc3 = ":"
// практический пример
CGRect rect = CGRectMake( 0, 0, 100, 100 );
NSValue* v = [ NSValue value: &rect withObjCType: @encode( CGRect ) ];
}
@compatibility_alias
Позволяет вам задать псевдоним для существующего класса. Первый параметр — имя псевдонима для имени класса, класса с таким именем не должно существовать. Второй параметр — имя существующего класса, для которого создается псевдоним.
@compatibility_alias AliasClassName ExistingClassName
После этого, вы можете использовать AliasClassName вместо ExistingClassName. Это может быть полезно после переименования класса без изменения его поведения. Вы можете использовать @compatibility_alias для того, чтобы не делать много изменений в существующем коде.
@«string»
Объявляет константный объект класса NSString. Для таких строк не требуется вызывать retain или release.
-( void ) aMethod
{
NSString* str = @"This is a constant string.";
NSUInteger strLength = [ @"This is legal!" length ];
}
Заключение
Я надеюсь, что вам понравился этот список, и он будет полезен вам. Если есть какие-то директивы, которых нет в списке, пожалуйста опишите их в комментариях к статье. Буду очень благодарен.
По мотивам тут.
-
mrdekk,
- 27 января 2012, 21:21
- рейтинг: +6
Похожие записи