翻译自:Objective-C Class Properties

译者:Haley_Wong

由于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类接口,它看起来是这样的:

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

下面来说明一下我们这两个类属性,第一个是只读的integer类型,第二个是可读可写具有copy特性的NSUUID类型。要注意有属性声明的类。

实现也很简单,我们首先需要存储 identifieruserCount 类属性。由于它们是类级别的也不是实例变量,因此我们把他们声明为静态的:

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

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

+ (NSInteger)userCount {
return _userCount;
}

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

+ (NSUUID *)identifier {
if (_identifier == nil) {
_identifier = [[NSUUID alloc] init];
}
return _identifier;
} + (void)setIdentifier:(NSUUID *)newIdentifier {
if (newIdentifier != _identifier) {
_identifier = [newIdentifier copy];
}
}

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

- (instancetype)init
{
self = [super init];
if (self) {
_userCount += 1;
}
return self;
}

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

+ (void)resetIdentifier {
_identifier = [[NSUUID alloc] init];
} @end

我们可以在类名后使用点语法来获取到类属性:

User.userCount;
User.identifier;

这里有一个关于User类用法的例子:

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);

这是输出:

// 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 后的样子:

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

(译)Objective-C 类属性的更多相关文章

  1. [译]JavaScript需要类吗?

    [译]JavaScript需要类吗?   原文:http://www.nczonline.net/blog/2012/10/16/does-javascript-need-classes/ 译者注:在 ...

  2. Python 中使用动态创建类属性的机制实现接口之后的依赖

    我们在自动化测试中经常会需要关联用例处理,需要动态类属性: 推荐使用第二种方法: 创建:setattr() 获取:getattr() 两种,如何创建 类属性 loan_id # 第一种,创建 # 类名 ...

  3. JavaScript类属性

    对象的类属性(class attribute)是一个字符串,用以表示对象的类型信息.ECMAScript3和ECMAScript5都未提供设置这个属性的方法,并只有一个间接的方法可以查询它.默认的to ...

  4. python 类属性与方法

    Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...

  5. 【Python】[面性对象编程] 获取对象信息,实例属性和类属性

    获取对象信息1.使用isinstance()判断class类型2.dir() 返回一个对象的所有属性和方法3.如果试图获取不存在的对象会抛出异常[AttributeError]4.正确利用对象内置函数 ...

  6. MyBatis学习总结(四)——解决字段名与实体类属性名不相同的冲突(转载)

    本文转载自:http://www.cnblogs.com/jpf-java/p/6013307.html 在平时的开发中,我们表中的字段名和表对应实体类的属性名称不一定都是完全相同的,下面来演示一下这 ...

  7. mybatis框架下解决数据库中表的列的字段名和实体类属性不相同的问题

    导包.... 实体类中的属性,getter,setter,tostring,构造等方法就不写了 private int id; private String orderNo; private floa ...

  8. 5.Swift枚举|结构体|类|属性|方法|下标脚本|继承

    1. 枚举: ->在Swift中依然适用整数来标示枚举值,需搭配case关键字 enum  Celebrity{  case DongXie,XiDu,Nandi,BeiGai }  // 从左 ...

  9. Python进阶(三)--global和类属性

    global关键字 一句话概括为:告诉python解释器,global声明的变量为全局作用域内定义的变量.解释器就会到全局作用域内寻找global定义的变量. python的类属性 类属性相当于其他O ...

随机推荐

  1. kubernetes controller 实现

    对于kubernetes中不存在的资源类型,我们可以通过自定义资源的方式进行扩展,首先创建customresourcedefinition对象定义资源及其schema,然后就可以创建自定义的资源了,但 ...

  2. 【转】JAVA异常报错大全

    算术异常类:ArithmeticExecption 空指针异常类:NullPointerException 类型强制转换异常:ClassCastException 数组负下标异常:NegativeAr ...

  3. 玩一玩基于Token的 自定义身份认证+权限管理

    使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录.大概的流程是这样的: 客户端使用用户名跟密码请求登录 服务端收到请求,去验证用户名与密码 验证成功后,服务端会签发一个 Toke ...

  4. c#代码输入图片

    Image bgimage = Image.FromFile(flieUrl + bgImg); if (bgimage != null) { Bitmap bmp1 = new Bitmap(bgi ...

  5. [LeetCode] Candy Crush 糖果消消乐

    This question is about implementing a basic elimination algorithm for Candy Crush. Given a 2D intege ...

  6. CSS常用字体属性(多出的文本隐藏,或者以省略号的形式显示)和背景样式以及背景图的2个不常用属性:background-origin和background-clip

    (一)常用的字体属性: font-weight: 属性值100-900  400等于正常 700等于bold ,数值越大,越粗 font-size:字体大小,单位可以为px或者% font-famil ...

  7. enumerate给列表加序号

    #coding=utf-8#给列表加上序号,enumerate(l1),默认从0开始l1=['money','house','joo']for item in enumerate(l1,1): #pr ...

  8. python数据挖掘_Json结构分析

    json是一种轻量级的数据交换格式,也可以说是一种配置文件的格式 这种格式的文件是我们在数据处理经常会遇到的 python提供内置的模块json,只需要在使用前导入即可 你可以通过帮助函数查看json ...

  9. [HNOI2016]最小公倍数

    题目描述 给定一张N个顶点M条边的无向图(顶点编号为1,2,...,n),每条边上带有权值.所有权值都可以分解成2a∗3b2^a*3^b2a∗3b 的形式. 现在有q个询问,每次询问给定四个参数u.v ...

  10. 洛谷P1397 [NOI2013]矩阵游戏

    矩阵快速幂+费马小定理 矩阵也是可以跑费马小定理的,但是要注意这个: (图是盗来的QAQ) 就是说如果矩阵a[i][i]都是相等的,那么就是mod p 而不是mod p-1了 #include< ...