Swift 3.0 令人興奮,但Objective-C也有小改進--Objective-C的類屬性

EliseNoskow 8年前發布 | 29K 次閱讀 Swift 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;. 

翻譯如下:

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類型。要注意有屬性聲明的類。

實現也很簡單,我們首先需要存儲 `identifier` 和 `userCount` 類屬性。由于它們是類級別的也不是實例變量,因此我們把他們聲明為靜態的:

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

現在我們必須為這兩個屬性創建 `getter` 和 `setter` 方法。在正式版說明里已經提到過,這些類屬性永遠不會被合成,所以如果 缺少 `getter` 或 `setter`,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 變量也將會是可選類型的。

 

 

來自:http://www.cocoachina.com/ios/20161202/18257.html

 

 本文由用戶 EliseNoskow 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!