我未能发现一份收集在一起的Objective-C编译指令列表。我们都了解像@interface和@implementation这样的关键词,但是很少了解@dynamic和@encode,甚至一点不懂。
神农曰:汝之!
尽管我已了解它们中的大部分,但是我总感觉我可能遗漏了其中的一些精华。因此我努力把所有的Objective-C 编译指令集中在一起,整理成章。
-
@class
-
@defs
-
@protocol @required @optional @end
-
@interface @public @package @protected @private @property @end
-
@implementation @systhesize @dynamic @end
-
@throw @try @catch @finally
-
@synchronized @autoreleasepool
-
@selector @encode
-
@compatibility_alias
-
@“string”
@class
用作类(class)的前置声明。不必引用头文件声明一个已知类。
@class ClassName;
神农曰:阉人,可用,不可繁衍生息!
注意:跟@protocol和@selector不同,你不能用下面的写法,通过名字获取类对象(Objecitve-c中类也是一种对象):
//错误,不能运行
Class c = @class(ClassName);
应该是这样
Class c = [ClassName class];
@defs
@defs指令返回一个Objective-C类的布局(类的本质是一种C struct,返回的就是struct的布局形式),它允许你使用与Objective-C类相同的布局创建一个C结构(struct)。如果你还不理解,Objective-C的类是通过基本的C结构添加方法实现的。你可以认为Objective-C就是C语言的一中扩展。
struct { @defs( NSObject ) }
@defs仅用在一些核心部分,底层Objective-C的操作和优化,Objective-C消息发送提速
神农曰:色者,食也!(hardcore有光明正大的性行为含义)
@protocol @required @optional @end
标记一个协议(protocol)的声明。一个@protocol可以选择声明它必须遵循的其他协议
@protocol ProcolName <aProtocol,anotherProtocol>
@required
// 必要声明
@optional
// 可选声明
@end
和@selector类似,你可以使用@protocol通过协议名称获取一个协议对象(协议也是对象哦!)
-(void) aMethod
{
Protocol *aProtocol = @protocol( ProtocolName );
}
依赖的指令
-
@required(默认) - @required下面的方法是必须实现的。(默认就是必须实现)
-
@optional - @optional下面的方法是可选的。类在实现一个协议的时候可以选择是否实现可选的方法。使用协议的类遵必须测试可选的协议方法是否可行。例如
[object respondsToSelector:@selector(optionalProtocolMethod)]; -
@end - 标记协议声明的结束
@interface @public @package @protected @private @property @end
标记一个类或者是类别的声明的开始
类声明
SuperClassName是可选的,Objective-C的类应该直接或间接继承自NSObject.定义类时,类声明的@interface可以选择声明遵循某些协议。
@interface ClassName : SuperClassName <aProtocol, anotherProtocol>
{
@public
// 全局可见 实例变量
@package
// 包可见 实例变量
@protected
// 受保护的 实例变量
@private
// 私有的 实例变量
}
// 声明属性
@property (atomic, readwrite, assign) id aProperty;
// 实例 或 类 方法的声明
@end
类别声明
Objective-C的类别不能添加实例变量.但是可以选择遵循遵循(增加)协议。[省略名称的类别][categroryName] (只留空括号)可以添加到实现文件(implementation file .m)中来实现方法的私有化(private)。
@interface ClassName (CategoryName) <aProtocol, anotherProtocol>
// 属性声明
@property (atomic, readwrite, assign) id aProperty;
// 方法声明
@end
依赖的指令
-
@public - 声明在@public指令下面的实例变量作为公共可见,公共实例变量可以通过指针读写
someObject->aPublicVariable = 10; -
@package - 声明在@package指令下面的实例变量在定义类的框架(Framework)内是可见的,定义类的框架外是私有的。这些程序仅用在64位系统,在32位系统把@package与@public同等对待
-
@protected(默认) - 声明在@protected下面的实例变量只有当前类和该类的子类可用
-
@private - 声明在@private指令下面的实例变量作为类的私有成员,即使继承自该类的子类也不能使用私有的实例变量。
-
@property - 声明一个属性,可以使用点记法操作。@property可以跟随可选的方括号,方括号里面通过下面的关键字(属性修改器)列举属性的扩展行为。这些属性修改器是:
-
readwrite(默认),readonly - readwrite生成修改方法和读取方法,readonly仅生成读取方法
-
assign(默认),retain,copy - 使得属性可以被恰当地安全分配给id. assign简单的赋予传过来的值。 retain发送release消息给已经存在的实例变量,然后发送retain消息给新对象,把这个添加的对象赋值给实例变量。copy发送releas消息给存在的实例变量,发送copy消息给新对象,把这个复制的对象赋值给实例变量。在后两种情况下,你仍可以通过发送release消息(或使用nil)去释放属性。
-
atomic(默认),nonatomic - 颗粒化的属性是线程安全的,非颗粒化的属性在多线程环境下容易引发同步错误。非颗粒化属性比颗粒化属性快,常用在单线程程序里,或是在你非常确定属性仅被一个线程使用的情况下。
-
weak(默认),strong - 在自动引用计数(ARC)启用情况下可用。strong与retain类似,week与assign类似,不同的是,weak属性被设置成nil,实例变量就会释放。注意,weak只有在ios5(或更高版本),和Mac OS 10.7(Lion)(或更新版本)中可用。
-
-
end - 标记类声明的结束
@implementation @synthesize @dynamic @end
标记一个类或者类别的实现
类实现
@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 - 告诉编译器对应(逗号区分)属性的设置器和读取器方法是必须的,将会通过人为实现,或在运行时动态产生。使用动态属性不会产生编译警告,即使设置器和读取器还没有实现。在属性读取器和设置器方法需要通过自定义代码实现的情况下,你可能想要使用@dynamcic。
-
@end - 标记类实现的结束
@throw @try @catch @finally
用来[处理和抛出异常][exceptions]
@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比使用NSAutoreleasePool快大约六倍,尽管苹果仍要求在非自动引用计数工程中使用NSAutorelaeasePool
你不应该在@autoreleasepool块内定义了变量在快外面使用该变量。这种代码应该被避免或者被重构。
-(void) aMethod
{
@autoreleasepool
{
// code that creates a large number of temporary objects
}
}
@selector
通过Objective-C方法返回一个选择器类型的SEL。如果方法没有被声明或不存在,将会产生编译警告。
-(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 = ":"
// practical example:
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对象。这种字符串不需要计数或释放。
-(void) aMethod
{
NSString* str = @"This is a constant string.";
NSUInteger strLength = [@"This is legal!" length];
}