由于Swift 3.0 出了太多令人兴奋的新特性,人们很容易忽略 Objective-C中的小改动。或许你会觉得苹果提及Objective-C 很可能是为了提高和Swift互操作性(译者注:互操作性主要是指OC代码与Swift代码相互转换),不过苹果仍然很欢迎开发者用Objective-C来完成工作。

在这篇文章中,我们就来看看Objective-C中新添加的类属性。
Objective-C 类属性
摘自 Xcode 8正式版中的说明:
Objective-C now supports class properties, which interoperate with Swift type properties. 
They are declared as: @property (class) NSString *someStringProperty;. 
They are never synthesized. (23891898)
翻译如下:

Objective-C 现在支持类属性了,与OC 中的类属性对应的是Swift的类型属性。
它们是这样声明的:@property (class) NSString *someStringProperty;
类属性永远不会被自动合成。
为了实践一下,我们来创建一个包含几个类型的简单 Objective-C 类。这是我们的 `User`类接口,它看起来是这样的:

1
2
3
4
5
@interface User : NSObject
@property (class, nonatomic, assign, readonly) NSInteger userCount;
@property (class, nonatomic, copy) NSUUID *identifier;
+ (void)resetIdentifier;
@end

下面来说明一下我们这两个类属性,第一个是只读的integer类型,第二个是可读可写具有copy特性的NSUUID类型。要注意有属性声明的类。
实现也很简单,我们首先需要存储 `identifier` 和 `userCount` 类属性。由于它们是类级别的也不是实例变量,因此我们把他们声明为静态的:

1
2
3
@implementation User
static NSUUID *_identifier = nil;
static NSInteger _userCount = 0;

现在我们必须为这两个属性创建 `getter` 和 `setter` 方法。在正式版说明里已经提到过,这些类属性永远不会被合成,所以如果 缺少 `getter` 或 `setter`,Xcode 将会报警告。第一个只读的`userCount`仅需要一个返回count 值的 getter 方法。 注意使用 `+`使我们的getter 方法变成一个类方法:

1
2
3
+ (NSInteger)userCount {
  return _userCount;
}

`identifier` 属性则 getter方法 和 setter 方法都需要。在getter 方法中,如果identifier为空,我们就新建一个identifier:

1
2
3
4
5
6
7
8
9
10
11
12
+ (NSUUID *)identifier {
  if (_identifier == nil) {
    _identifier = [[NSUUID alloc] init];
  }
  return _identifier;
}
 
+ (void)setIdentifier:(NSUUID *)newIdentifier {
  if (newIdentifier != _identifier) {
    _identifier = [newIdentifier copy];
  }
}

我们也为这个`User`类创建了一个会更新 count 属性的基本初始化方法。

1
2
3
4
5
6
7
8
- (instancetype)init
{
  self = [super init];
  if (self) {
    _userCount += 1;
  }
  return self;
}

`resetIdentifier`类方法 是一个能创建一个新的identifier 的便利方法:

1
2
3
4
5
+ (void)resetIdentifier {
  _identifier = [[NSUUID alloc] init];
}
 
@end

我们可以在类名后使用点语法来获取到类属性:
User.userCount;
User.identifier;
这里有一个关于User类用法的例子:

1
2
3
4
5
6
7
8
for (int i = 0; i < 3; i++) {
    self.user = [[User alloc] init];
    NSLog(@"User count: %ld",(long)User.userCount);
    NSLog(@"Identifier = %@",User.identifier);
}
 
[User resetIdentifier];    
NSLog(@"Identifier = %@",User.identifier);

这是输出:

1
2
3
4
5
6
7
// User count: 1
// Identifier = 4B98B7FD-F8DC-484A-92B2-B2BB20BCB709
// User count: 2
// Identifier = 4B98B7FD-F8DC-484A-92B2-B2BB20BCB709
// User count: 3
// Identifier = 4B98B7FD-F8DC-484A-92B2-B2BB20BCB709
// Identifier = A0519681-1E08-4DF2-B2D1-D077CF2BDEFF

注意:尽管这是Xcode 8 中 LLVM 编译器的新特性,但是它对于iOS 10之前的版本依然适用。
生成的Swift接口
似乎,Objective-C 最近的这些改进只是为了提高与Swift的互操作性。Objective-C中新添加的类型属性对应的是Swift中类变量的用法。下面这是我们 `User`类转换为 Swift 后的样子:

1
2
3
4
5
public class User : NSObject { 
  public class var userCount: Int { get }
  public class var identifier: UUID!   
  public class func resetIdentifier()
}

注意,identifier 类属性是一个会隐式解包的变量,意味着我们永远也不希望它为nil。为了允许它为nil,我们需要在Objective-C的属性声明里添加一个 `nullable`的标识。 我们的Swift 变量也将会是可选类型的。看 [Using nullable to annotate Objective-C]可以看到更多详细内容。
拓展阅读
WWDC 2016 Session 405 What’s New in LLVM

最新文章

  1. cookie自动登录的实现
  2. 微信公众号开发之被逼学web服务端1-----使用SecureCRT连接Linux服务器
  3. 数据可视化(7)--D3基础
  4. 给table行换色
  5. Swift闭包概念与常见使用场景总结
  6. SQL设置SQLServer最大连接数查询语句
  7. 4. Median of Two Sorted Arrays
  8. CAF(C++ actor framework)(序列化之类,无需序列化,直接传)(二)
  9. AFNetworking2.x 使用过程中遇到的问题
  10. MSSQLSERVER数据库- 解决不允许保存更改表结构
  11. Firebird/InterBase内置函数使用说明
  12. mp4文件格式之fragment mp4
  13. jQuery.fn.extend与jQuery.extend 的区别
  14. cowboy rest
  15. 关于在git添加远程地址的过程中遇到的问题
  16. 201521123048 《java程序设计》 第10周学习总结
  17. SQL语句的CRUD
  18. odoo 配置文件参数大全
  19. element 多个文件上传多次http请求解决方法
  20. JQuery POST请求封装

热门文章

  1. 并查集(HDOJ 1856)
  2. JAVA课程实验报告 实验五 Java网络编程及安全
  3. HTML DOM appendChild() 方法
  4. 64位Win7下运行ASP+Access网站的方法
  5. Spring —— 三种配置数据源的方式:spring内置、c3p0、dbcp
  6. 创建 XMLHttpRequest 对象
  7. html 表格的制作
  8. Java 基础知识总结 (三、运算符)
  9. Pig Latin
  10. mysql学习-windows下绿色版mysql安装问题解决办法