由于Swift3.0 出了太多令人興奮的新特性,人們很容易忽略Objective-C中的小改動(dòng)。蘋果展示Objective-C 很可能是為了提高Swift互操作性(譯者注:互操作性主要是指OC代碼與Swift代碼相互轉(zhuǎn)換),但是仍然很歡迎開發(fā)者用Objective-C來完成工作。
在這篇文章中,我們就來看看Objective-C中新添加的類屬性。
摘自 Xcode 8正式版中的說明:
Objective-C now supportsclassproperties,whichinteroperatewithSwifttypeproperties.
They are declared as:@property(class) NSString *someStringProperty;.?
They are never synthesized. (23891898)
Objective-C現(xiàn)在支持類屬性了,與OC中的類屬性對應(yīng)的是Swift的類型屬性。
它們是這樣聲明的:@property(class)NSString*someStringProperty;
類屬性永遠(yuǎn)不會被自動(dòng)合成。
為了實(shí)驗(yàn)一下,我們來創(chuàng)建一個(gè)包含幾個(gè)類型的簡單 Objective-C 類。這是我們的User類接口,它看起來是這樣的:
@interfaceUser:NSObject
@property class,nonatomic,assign,readonly) NSInteger userCount;
@property (class,nonatomic, copy) NSUUID *identifier;
+ (void)resetIdentifier;
@end
下面來說明一下我們這兩個(gè)類屬性,第一個(gè)是只讀的integer類型,第二個(gè)是可讀可寫具有copy特性的NSUUID類型。要注意有屬性聲明的類。
實(shí)現(xiàn)也很簡單,我們首先需要存儲identifier和userCount類屬性。由于它們是類級別的也不是實(shí)例變量,因此我們把他們聲明為靜態(tài)的:
@implementation
UserstaticNSUUID *_identifier =nil;
staticNSInteger_userCount =0;
現(xiàn)在我們必須為這兩個(gè)屬性創(chuàng)建getter和setter方法。在正式版說明里已經(jīng)提到過,這些類屬性永遠(yuǎn)不會被合成,所以如果 缺少getter或setter,Xcode 將會報(bào)警告。第一個(gè)只讀的userCount僅需要一個(gè)返回count 值的 getter 方法。 注意使用+使我們的getter 方法變成一個(gè)類方法:
+ (NSInteger)userCount {return_userCount;}
identifier屬性則 getter方法 和 setter 方法都需要。在getter 方法中,如果identifier為空,我們就新建一個(gè)identifier:
+ (NSUUID *)identifier {
if(_identifier ==nil) {?
?? _identifier = [[NSUUID alloc] init];?
?}
return_identifier;
}
+ (void)setIdentifier:(NSUUID *)newIdentifier {
if(newIdentifier != _identifier) {?
?? _identifier = [newIdentifier copy];?
?}
}
我們也為這個(gè)User類創(chuàng)建了一個(gè)會更新 count 屬性的基本初始化方法。
- (instancetype)init{
self= [superinit];
if(self) {
? ? _userCount +=1;??
}returnself;
}
resetIdentifier類方法 是一個(gè)能創(chuàng)建一個(gè)新的identifier 的便利方法:
+ (void)resetIdentifier {?
?_identifier = [[NSUUID alloc] init];
}
@end
我們可以在類名后使用點(diǎn)語法來獲取到類屬性:
User.userCount;User.identifier;
這里有一個(gè)關(guān)于User類用法的例子:
for(inti =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 編譯器的新特性,但是它對于iOS10之前的版本依然適用。
似乎,Objective-C 最近的這些改進(jìn)只是為了提高與Swift的互操作性。Objective-C中新添加的類型屬性對應(yīng)的是Swift中類變量的用法。下面這是我們User類轉(zhuǎn)換為 Swift 后的樣子:
publicclassUser : NSObject {
publicclassvaruserCount: Int {get}publicclassvaridentifier: UUID!publicclassfuncresetIdentifier()
}
注意,identifier 類屬性是一個(gè)會隱式解包的變量,意味著我們永遠(yuǎn)也不希望它為nil。為了允許它為nil,我們需要在Objective-C的屬性聲明里添加一個(gè)nullable的標(biāo)識。 我們的Swift 變量也將會是可選類型的。看Using nullable to annotate Objective-C可以看到更多詳細(xì)內(nèi)容。