在学习和使用Objective-c语言的时候,我们随处可见‘@’符号,这和其他语言有很大不同。像是Python里面的装饰器,或是某种Syntactic sugar(语法糖)。
由于c、c++本身没有‘@’,Oc这样设计可能是为了更好地和c、c++混编,因为不用担心关键字冲突。正如这篇文章所提到的。不过‘@’的用途多种多样,我感觉还是需要整理一下。
- @class
- @defs
- @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”
- @’a’ @1 @YES
- @[]
- @{}
- @()
以上涉及的这些,有的十分常见,也有的基本用不到。下面我们就给几个不常见的,或者比较重要的并且容易忽视的用法,总结一下。
@compatibility_alias
关于@compatibility_alias的用法,Mattt Thompson大大举过很好的示例。在iOS5下想使用collectionView的效果,无疑PSTCollectionView 是最佳的替代方案,下面的代码,可以为PSTCollectView起个别名。这样在iOS5我们也可以制造出使用UICollectionView的幻觉,重点是以后升级可以省去很多麻烦:
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000
@compatibility_alias UICollectionViewController PSTCollectionViewController;
@compatibility_alias UICollectionView PSTCollectionView;
@compatibility_alias UICollectionReusableView PSTCollectionReusableView;
@compatibility_alias UICollectionViewCell PSTCollectionViewCell;
@compatibility_alias UICollectionViewLayout PSTCollectionViewLayout;
@compatibility_alias UICollectionViewFlowLayout PSTCollectionViewFlowLayout;
@compatibility_alias UICollectionViewLayoutAttributes PSTCollectionViewLayoutAttributes;
@protocol UICollectionViewDataSource <PSTCollectionViewDataSource> @end
@protocol UICollectionViewDelegate <PSTCollectionViewDelegate> @end
#endif
Object Literals
2012年苹果加入了如下字面值,简化了代码。
NSArray Literal: @[ ]
NSArray * array = @[ @1, @"b", @YES];
id str = array[0];
NSDictionary Literal: @{ }
NSDictionary * dict = @{ @"key1" : @"obj1", @"key2" : @"obj2"};
id obj1 = dict[@"key1"];
NSNumber Literal:
NSNumber * number = @'a';//([NSNumber numberWithChar:'a'])
NSNumber * number = @1;//([NSNumber numberWithInt:1])
NSNumber * number = @12ll;//([NSNumber numberWithLongLong:12ll])
NSNumber * number = @12ul;//([NSNumber numberWithUnsignedLong:12ul])
NSNumber * number = @12.3f;//([NSNumber numberWithFloat:12.3f])
NSNumber * number = @YES;//([NSNumber numberWithBool:YES])
NSSet Literal:
以上应该大部分集合类的literal都有了,不过类似的NSSet Literal还没有提供。
我们可以用数组初始化的方式:
NSSet * set = [NSSet setWithArray:@[@"yes",@YES]];
当然我们也可以通过自己宏定义来实现:
#define $(...) [[NSSet alloc] initWithObjects:__VA_ARGS__, nil]
//或者
#define $(...) [NSSet setWithObjects:__VA_ARGS__, nil]
//这样就可以用了:
NSSet *set = $(@"hello",@"world",@"!");
Expressions:@( )
@( ),会动态评估里面的表达式。返回值:计算后的表达式值的对象常量。如
[@("hello word") class] //返回类型 NSString
[@(77 - 88) class] //返回类型 NSNumber。
@encode
返回一个的char 类型的类型编码,苹果官方文档有介绍
const char objCType = @encode(float);
printf(“%s”,objCType);
@defs
我们都知道,Oc的类是在c语言的结构体的基础上建立起来的。@defsd会返回Objective-C类相同的布局,例如下述代码,会得到一个相同结构的结构体。
struct cStructure
{
@defs(NSObject);
} *cStruct;
不过,如果你现在尝试如上代码,你会得到:@defs is not support on this platform now 或者 @defs is no longer supported in new ABI(Application Binary Interface)的错误。因为大概xcode3.2后我们就已经无法在现在的Objective-C中使用它了。