NS_OPTIONS在swift中怎麼實現?

來源:互聯網
上載者:User

標籤:

       今天在一個ios培訓網站上看到一篇部落格,講的是在NS_OPTIONS在Swift中的實現,寫得還算比較深刻全面,小編對其進行整理後,分享出來,希望對大家在iOS應用開發上有所協助吧。

       在iOS開發中,我們常常需要定義一個枚舉,以替代C語言枚舉的定義方式,常用的方法就是在Objective-C中使用NS_ENUM和NS_OPTIONS。其中,NS_ENUM用於定義普通的枚舉,NS_OPTIONS用於定義選項類型的枚舉。

      不同於Objective-C語言,Swift中的枚舉增加了更多特性,它可以包含原始類型(不再局限於整型)以及相關值。正是由於這些新增的特性,枚舉在Swift中得到了更廣泛的應用。在Foundation中,Objective-C中的NS_ENUM類型的枚舉,都會自動轉換成Swift中enum,並且更加精鍊。以Collection View的滾動方向為例,在Objective-C中,其定義如下:

 

typedef NS_ENUM(NSInteger, UICollectionViewScrollDirection) {

  UICollectionViewScrollDirectionVertical,

  UICollectionViewScrollDirectionHorizontal

};

而在Swift中,其定義如下:

 

enum UICollectionViewScrollDirection : Int {

  case Vertical

  case Horizontal

}

       從上面這兩段代碼中,也可以看出swift中的實現確實精練了很多,在以後代碼的維護上也方便。在編碼中,定義枚舉時,採用哪種方式,你應該清楚了吧。

不過對於Objective-C中NS_OPTIONS類型的枚舉,Swift中的實現似乎就沒有那麼美好了。我們再來對比一下UICollectionViewScrollPosition的定義吧,在Objective-C中,其定義如下:

 

typedef NS_OPTIONS(NSUInteger, UICollectionViewScrollPosition) {

    UICollectionViewScrollPositionNone                 = 0,

 

    // The vertical positions are mutually exclusive to each other, but are bitwise or-able with the horizontal scroll positions.

    // Combining positions from the same grouping (horizontal or vertical) will result in an NSInvalidArgumentException.

    UICollectionViewScrollPositionTop                  = 1 << 0,

    UICollectionViewScrollPositionCenteredVertically   = 1 << 1,

    UICollectionViewScrollPositionBottom               = 1 << 2,

 

    // Likewise, the horizontal positions are mutually exclusive to each other.

    UICollectionViewScrollPositionLeft                 = 1 << 3,

    UICollectionViewScrollPositionCenteredHorizontally = 1 << 4,

    UICollectionViewScrollPositionRight                = 1 << 5

};

而在Swift 2.0中,其定義如下:

 

struct UICollectionViewScrollPosition : OptionSetType {

    init(rawValue: UInt)

 

    static var None: UICollectionViewScrollPosition { get }

 

    // The vertical positions are mutually exclusive to each other, but are bitwise or-able with the horizontal scroll positions.

    // Combining positions from the same grouping (horizontal or vertical) will result in an NSInvalidArgumentException.

    static var Top: UICollectionViewScrollPosition { get }

    static var CenteredVertically: UICollectionViewScrollPosition { get }

    static var Bottom: UICollectionViewScrollPosition { get }

 

    // Likewise, the horizontal positions are mutually exclusive to each other.

    static var Left: UICollectionViewScrollPosition { get }

    static var CenteredHorizontally: UICollectionViewScrollPosition { get }

    static var Right: UICollectionViewScrollPosition { get }

}

光看代碼,不看實現,這也是化簡為繁的節奏。

為什麼要在swift中這樣做呢?Mattt給我們的解釋是:

由於Swift不支援C語言中枚舉值的整型掩碼操作的技巧,在Swift中,一個枚舉可以表示一組有效選項的集合,但卻沒有辦法支援這些選項的組合操作(“&”、”|”等)。理論上,一個枚舉可以定義選項值的任意組合值,但對於n > 3這種操作,卻無法有效支援。

 

為了支援類NS_OPTIONS的枚舉,Swift 2.0中定義了OptionSetType協議,它的聲明如下:

 

/// Supplies convenient conformance to `SetAlgebraType` for any type

/// whose `RawValue` is a `BitwiseOperationsType`.  For example:

///

///     struct PackagingOptions : OptionSetType {

///       let rawValue: Int

///       init(rawValue: Int) { self.rawValue = rawValue }

///    

///       static let Box = PackagingOptions(rawValue: 1)

///       static let Carton = PackagingOptions(rawValue: 2)

///       static let Bag = PackagingOptions(rawValue: 4)

///       static let Satchel = PackagingOptions(rawValue: 8)

///       static let BoxOrBag: PackagingOptions = [Box, Bag]

///       static let BoxOrCartonOrBag: PackagingOptions = [Box, Carton, Bag]

///     }

///

/// In the example above, `PackagingOptions.Element` is the same type

/// as `PackagingOptions`, and instance `a` subsumes instance `b` if

/// and only if `a.rawValue & b.rawValue == b.rawValue`.

protocol OptionSetType : SetAlgebraType, RawRepresentable {

 

    /// An `OptionSet`‘s `Element` type is normally `Self`.

    typealias Element = Self

 

    /// Convert from a value of `RawValue`, succeeding unconditionally.

    init(rawValue: Self.RawValue)

}

從字面上來看,OptionSetType是選項集合類型,它定義了一些基本操作,包括集合操作(union, intersect, exclusiveOr)、成員管理(contains, insert, remove)、位操作(unionInPlace, intersectInPlace, exclusiveOrInPlace)以及其它的一些基本操作。

 

作為樣本,我們來定義一個表示方向的選項集合,通常我們是定義一個實現OptionSetType協議的結構體,如下所示:

 

struct Directions: OptionSetType {

 

    var rawValue:Int

    init(rawValue: Int) {

        self.rawValue = rawValue

    }

 

    static let Up: Directions = Directions(rawValue: 1 << 0)

    static let Down: Directions = Directions(rawValue: 1 << 1)

    static let Left: Directions = Directions(rawValue: 1 << 2)

    static let Right: Directions = Directions(rawValue: 1 << 3)

}

所需要做的基本上就是這些。然後我們就可以建立Directions的執行個體了,如下所示:

 

let direction: Directions = Directions.Left

if direction == Directions.Left {

    // ...

}

如果想同時支援兩個方向,則可以如上處理:

 

let leftUp: Directions = [Directions.Left, Directions.Up]

if leftUp.contains(Directions.Left) && leftUp.contains(Directions.Up) {

    // ...

}

如果leftUp同時包含Directions.Left和Directions.Up,則返回true。

 

這裡還有另外一種方法來達到這個目的,就是我們在Directions結構體中直接聲明聲明Left和Up的靜態常量,如下所示:

 

struct Directions: OptionSetType {

 

    // ...

    static let LeftUp: Directions = [Directions.Left, Directions.Up]

    static let RightUp: Directions = [Directions.Right, Directions.Up]

    // ...

}

這樣,我們就可以以如下方式來執行上面的操作:

 

if leftUp == Directions.LeftUp {

    // ...

}

當然,如果單一選項較多,而要去組合所有的情況,這種方法就顯示笨拙了,這種情況下還是推薦使用contains方法。

 

      總體來說,雖然Swift中的對選項的支援沒有Objective-C中的NS_OPTIONS來得簡潔方便,但相比Swift 1.2,Swift 2.0已經有了很大的改善。Swift作為一門新的iOS開發語言,其很多方面在Objective-C的基礎上都有了很大的改善,且swift成為今後iOS開發主流語言是必然,所以對於NS_OPTIONS的實現,大家還是需要嘗試用Swift語言,慢慢習慣就好了。

 

NS_OPTIONS在swift中怎麼實現?

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.