背景
项目里现在经常见到Objective-C的代码,swift代码写多了,类变量直接就是一个属性搞定,例如:
class ClassA: NSObject {
static var proA = ""
}
某天到了OC代码需要写一个类变量,发现自己回想不起来如何定义一个类属性,今天来看看OC的类属性。
属性定义的方式
首先,声明一个实例属性的方式大家应该都知道:
@property(nonatomic, copy) NSMutableDictionary *DictionaryA;
那么问题就来了,属性修饰符(nonatomic 等)里边并没有类变量的选项。 类型定义的方式前加class变成
class NSMutableDictionary *DictionaryA
编译器直接报错。说明这种方式不行。
除此之外大家平时应该在某些.m文件中见过这样的定义方式:
NSInteger const classInteger = 0;
@implementation ClassA
@end
这实际是定义了一个静态变量。静态变量的作用域就是这个.m文件范围内。这也就意味着我们可以在这个.m文件的任何位置访问这个变量。这是不是很像我们swift里的类变量了。
方案
有了前边的讨论,我们可以知道Objective-C可以在实现文件中定义静态变量,以此来实现类变量的效果。有了这个结果我们就可以解决本类内部需要类变量的需求了。自然有人问了,那么子类呢? 前述静态变量的作用域只在本文件有效,也就意味着只有本类的类方法和实例方法可以访问这个变量,子类访问不到。我们来看下面的方法
类方法定义
大家都知道类方法的定义吧,例如:
+ (instancetype) shardInstance;
这样的方法会返回一个类的实例。Objective-C中子类是可以继承父类的属性和方法的,而我们的类方法又可以访问我们的类变量,所以有了下面的解决方案
解决方法
我们可以在本类的声明中声明一些类方法充当静态变量的getter和setter方法。然后子类来使用这些方法。
当然这会造成其他的类也能访问我们的类变量。实际上Objective-C中类变量因为是静态变量,设计的初衷就是只在类的内部使用,所以我们在提供方法的时候需要认真考虑这一点。
结论
Objective-C里声明类属性可以通过声明类方法和定义静态变量来实现。但是写代码的时候,就要考虑下是不是应该让外部访问我们的类变量。毕竟,'敲那什么的'(援引自某天听到的对这行的描述)和 一个好的工程师,差距就在这里了。