返回 登录
0

Objective-C的类属性

英文来源: Objective-C Class Properties,感谢作者对本篇文章的翻译授权。
作者: Andrew Madsen(@armadsen),Mac及iOS应用程序开发者,电气工程师。
译者: 白云鹏,移动应用开发者,个人博客:http://baiyunpeng.com

当把iOS 10和macOS 10.12 Sierra基础类库的Release Notes看过以后,我注意到了在“Overall API Updates”下面有一项内容。

在Swift和Objective-C两者中类属性的用法,最后使用了新的声明规则:“@property (class)”。

Xcode 8包括了Clang和LLVM(800.0.2.24.1和8.0.0,8.0.0是首个beta版)的新版本。新版的Clang添加了Objective-C对类属性的支持。该特性在我所看到过的文档中,还没有被完全记录。所以我做了一项小实验。

比如有一个叫做Car的类,可以创建可配置默认颜色的cars,在Swift中,可以这样做:

class Car {
    static var defaultColor: UIColor?
}

之前在Objective-C中,可能会这样做:

@interface Car:NSObject
+(UIColor *)defaultColor;
+(UIColor *)setDefaultColor:(UIColor *) defaultColor;
@end

这种创建方法一直是一种相当常见的方法。对应的也就是实例属性的访问方法。在OS X(现macOS)和iOS的系统框架中,这种用法很常见。

有了Objective-C的这种新的类属性,我们可以像下面这样去声明接口:

@interface Car: NSObject
@property (class) UIColor *defaultColor
@end

接口声明中的@property代表这事一个类属性,而不是实例属性。

关键是要注意,不像常规的实例属性。Objective-C的实例属性不能够使用@synthesize,也不能通过编译器做这样的事。我们要负责实现属性自己的访问方法(也可以使用@dynamic告诉编译器,访问方法会在运行时提供)。如果没有对属性提供存取方法的话,就会得到编译警告,@synthesize也会产生一个编译错误:

方法的实现方式完全取决于类属性,但很常见的一种做法就是回过头来设置一个静态变量:

static UIColor *_carDefaultColor = nil;
@implemention Car

+(UIColor *)defaultColor { return _carDefaultColor; }
+(void)setDefaultColor:(UIColor *)defaultColor { _carDefaultColor = defaultColor; }

@end

似乎可以肯定地说,这个新添加的特性,是为了更好地与Swift衔接,与已存在的类的属性衔接。在真正的Objective-C类属性出现之前,我们恐怕要使用调用方法和函数的语法来对属性进行访问。

Car.setDefaultColor( .white() )

现在,在Swift中使用Objective-C类的属性,我们就可以使用常规的访问属性的语法来访问类的属性了。

Car.defaultColor = .white()

当然,即使对于纯Objective-c的代码,这个特性也有不小的好处。我们可以使用点号访问类的属性:

Car.defaultColor = [UIColor whiteColor];

在适宜的情况下,苹果公司大概会在系统API中使用这种新的Objective-C类属性,在Swift中的改进衔接方式。目前不太好说,苹果是否会回过头去更新现有的API,使用新的语法。目前为止,仅有NSWindow中的NSGridView和allowsAutomaticWindowTabbing使用了新的语法规则(macOS Sierra 10.12版本中两个新的API),但这种状况也许会发生改变。

在Objective-C中能够持续看到更新当然好了。就像去年出现的轻量级范型等这些新特性。即使引入的这些新特性主要是为了与Swift语言更好地衔接,但对Objective-C程序员来说,这样的更新实际上为Objective-C做出了不错的改进。

第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。

评论