Swift 3.0 令人兴奋,但Objective-C也有小改进--Objective-C的类属性
由于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 Userstatic 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
Swift 3.0 令人兴奋,但Objective-C也有小改进--Objective-C的类属性的更多相关文章
- fir.im Weekly - Swift 3.0 的迁移适配指南
无论你是移动开发者,还是桌面端开发者,或者正在IoT领域探索的技术人员,那么应该更加关注 iDev 全平台开发者大会,也许是后半年 iOS 开发者最盛大的技术盛宴.既有知名公司带来专业视野,又有从 S ...
- Swift 2.0初探
转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心. 今年6月,一年一度的WWDC大会如期而至,在大会上Apple发布了Swift 2.0,引 ...
- iOS开发——新特性OC篇&Swift 2.0新特性
Swift 2.0新特性 转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度 ...
- Swift 2.0初探:值得注意的新特性
转眼间,Swift已经一岁多了,这门新鲜.语法时尚.类型安全.执行速度更快的语言已经渐渐的深入广大开发者的心.我同样也是非常喜爱这门新的编程语言. 今年6月,一年一度的WWDC大会如期而至,在大会上A ...
- Swift 3.0项目迁移的一些记录
刚执行完Convert后报错600+,真是令人奔溃. 之后重新编译,仔细分析后发现其实真实错误远没有那么多.最终实际修改到的错误也就几十个,而且其中某些还是同一种错误. 这个项目是一个供自己使用的浏览 ...
- iOS开发系列--Swift 3.0
概述 从写第一篇Swift文章的时候到现在Swift已经从1.2发展到了今天的3.0,这期间由于Swift目前还在发展阶段并不能向下兼容,因此第一篇文章中的部分代码在当前的Xcode环境中已经无法运行 ...
- Swift 3.0 【Swift 3.0 相较于 Swift 2.2 的变化】
一.编译器和语法变化 函数或方法参数 调用函数或方法时从第一个参数开始就必须指定参数名 在Swift的历史版本中出现过在调用函数时不需要指定任何函数参数(或者从第二个参数开始指定参数名),在调用方法时 ...
- Swift 2.x -> Swift 3.0
Swift 3.0 相对于 2.x 有很大变化.特别是因为命名习惯的改变,导致许多 Api 都发生了变化.总的趋势是让表示更简洁. 对旧的代码升级,大部分可以根据提示来进行更正.但也有的需要手动修改. ...
- Swift 2.0 异常处理
转自:http://www.jianshu.com/p/96a7db3fde00 WWDC 2015 宣布了新的 Swift 2.0. 这次重大更新给 Swift 提供了新的异常处理方法.这篇文章会主 ...
随机推荐
- vagrant系列教程(三):vagrant搭建的php7环境(转)
原文:http://blog.csdn.net/hel12he/article/details/51107236 前面已经把vagrant的基础知识已经基本过了一遍 了,相信只要按着教程来,你已经搭建 ...
- Shell_参数替换(転)
From: http://www.cnblogs.com/yjf512/archive/2013/06/03/3114803.html Bash中的$符号的作用是参数替换,将参数名替换为参数所代表的值 ...
- Corba、protocol buffer、SOA的区别 (转)
From: http://www.zhihu.com/question/20279489 Google的protocol buffers?这个跟corba.soa没啥关系,不同层次的概念,没法比.pr ...
- 基于WDF的PCI/PCIe接口卡Windows驱动程序(4)- 驱动程序代码(源文件)
原文出处:http://www.cnblogs.com/jacklu/p/4687325.html 本篇文章将对PCIe驱动程序的源文件代码作详细解释与说明.整个WDF驱动程序工程共包含4个头文件(已 ...
- Objective c, +load, +initialize 方法
+load() 当类被加载入程序的时候会执行+load方法 +initialize() 当类第一次被使用的时候会执行+initialize方法 这两个方法都只会被执行一次.
- knockoutJS+knockout.multimodels使用记录
可以多次绑定,但不能嵌套绑定 错误示例: <div class="con_c" data-model="viewModel"> <div da ...
- sql server 行转列解决方案
主要应用case语句来解决行转列的问题 行转列问题主要分为两类 1)简单的行转列问题: 示例表: id sid course result 1 2005001 语文 ...
- LoadRunner ---思考时间设置
用户访问某个网站或软件,一般不会不停地做个各种操作,例如一次查询,用户需要时间查看查询的结果是否是自己想要的.例如一次订单提交,用户需要时间核对自己填写的信息是否正确等. 也就是说用户在做某些操作时, ...
- flume远程调试
项目开发的时候,出现问题的时候,通常在IDE里面直接进行调试,但有时候我们可能用的是另外的一些开源框架,甚至运行程序里面没有一行代码是我们自己写的,如果出现一些较复杂的问题,那么我们可能就会用到远程调 ...
- POJ 2010 - Moo University - Financial Aid 初探数据结构 二叉堆
考虑到数据结构短板严重,从计算几何换换口味= = 二叉堆 简介 堆总保持每个节点小于(大于)父亲节点.这样的堆被称作大根堆(小根堆). 顾名思义,大根堆的数根是堆内的最大元素. 堆的意义在于能快速O( ...