我们都知道在 swift 中很容易就能为一个类添加一个类属性,就像这样public static var name:String?,可在 OC 中我们应该怎么为一个类添加类属性呢?
我们可以在属性的描述词里添加一个 class 的描述,如下所示
1 | @interface SPCustomType : NSObject |
2 | //在这添加了一个class,代表着这是一个类属性 |
3 | @property (nonatomic,copy,class)NSString *name; |
4 | @property (nonatomic,assign,class)NSInteger count; |
5 | @end |
但是值得注意的是,Xcode 并不会为我们自动生成一个对应的类变量,也就是说@property (nonatomic,copy,class)NSString *name;相当于写成这样+ (NSString *)name;+ (void)setName:(NSString *)name;,有一个+号的 getter 和一个+号 setter 方法,所以我们需要去实现这 2 个类方法。
1 | @implementation SPCustomType |
2 | static NSString *_name; |
3 | static NSInteger _count; |
4 | + (NSString *)name{ |
5 | return _name; |
6 | } |
7 | + (void)setName:(NSString *)name{ |
8 | _name = name; |
9 | } |
10 | + (NSInteger)count{ |
11 | return _count; |
12 | } |
13 | + (void)setCount:(NSInteger)count{ |
14 | _count = count; |
15 | } |
16 | @end |
接下来我们就可以用类属性了。例如
1 | SPCustomType.count++; |
2 | NSLog(@"%ld",(long)SPCustomType.count);//打印结果是1 |
3 | SPCustomType.name = @"testName"; |
4 | NSLog(@"%@",SPCustomType.name);//打印结果是testName |
有的人会有疑问,既然加上class这个描述词之后,仅仅相当于生成了+号 getter 和 setter 方法的声明,那为什么我们能通过点语法进行调用呢?
其实点语法并不是去访问成员变量,而是方法的调用。ClassA.test相当于[ClassA test],ClassA.test=@"test"相当于[ClassA setTest:"test"]ClassA 既可以是一个对象也可以是一个类.简单测试如下
1 | //声明 |
2 | @interface SPDotTestClass : NSObject |
3 | + (void)sayHello; |
4 | + (void)setName:(NSString *)name; |
5 | @end |
6 | //实现 |
7 | @implementation SPDotTestClass |
8 | + (void)sayHello{ |
9 | NSLog(@"sayHello"); |
10 | } |
11 | + (void)setName:(NSString *)name{ |
12 | NSLog(@"hello %@",name); |
13 | } |
14 | @end |
15 | //测试代码 |
16 | SPDotTestClass.sayHello;//此处打印sayHello |
17 | SPDotTestClass.name = @"lkk";//此处打印hello lkk |
还有更简单的证明,就是我们经常用的[UIApplication sharedApplication];也可以写成UIApplication.sharedApplication;当然不建议这么去写。
在回到上面为 OC 添加类属性上,并不是真正的为一个类添加了类属性,只是看起来好像有了个类属性。添加类属性这个功能应该是为了更好的兼容 Swift