<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Swift Nullability and Objective-C 通過Bridging-Header文件,Swift可以與Objective-C無縫調用,但是Swift與Objective-C有一個很大的不同點:Swift支持`Optional`類型。比如`NSView`和`NSView?`,在Objective-C里對此只有一種表示,即`NSView *`,既可以用來表示該View為nil、也能表示為非nil,此時Swift編譯器是無法確定這個NSView是不是`Optional`類型的,這種情況下Swift編譯器會把它當作`NSView!`處理,隱式拆包。 在早期發布的Xcode版本中,蘋果的一些框架針對Swift的Optional類型進行了一些專門審查,使他們的API能夠適配Optional,而Xcode 6.3的發布,給我們帶來了Objetive-C的一個新特性:`nullability`注解,利用該特性我們也能對自己的代碼進行類似的處理。 ## 核心:__nullable 和 __nonnull 這個功能給我們帶來了兩個新的類型注解:`__nullable`和`__nonnull`,就像你看到的,`__nullable`可以表示一個`NULL`或者`nil`值,而`__nonnull`則剛好相反。如果你違反了這個規則,你將會收到編譯器的警告: ~~~ @interface AAPLList : NSObject <NSCoding, NSCopying> //--- - (AAPLListItem * __nullable)itemWithName:(NSString * __nonnull)name; @property (copy, readonly) NSArray * __nonnull allItems; //--- @end //-------------- [self.list itemWithName:nil]; // warning! ~~~ 你能在任何地方使用`__nullable`和`__nonnull`關鍵字,比如和標準C的`const`一起使用,也能直接應用到指針上。但是在大多數情況下,你會以優雅的方式寫下這些注解:在方法定義或聲明里,只要類型是一個簡單的對象或者Block指針,你就能以***不帶下劃線***的方式(`nullable`或`nonnull`)直接寫在左括號后面: ~~~ - (nullable AAPLListItem *)itemWithName:(nonnull NSString *)name; - (NSInteger)indexOfItem:(nonnull AAPLListItem *)item; ~~~ 對于`@property`,你也能以同樣的方式寫在它的屬性列表里: ~~~ @property (copy, nullable) NSString *name; @property (copy, readonly, nonnull) NSArray *allItems; ~~~ 不帶下劃線的形式比帶下劃線的形式看起來更簡潔,但你仍然需要將它們應用到頭文件的每一個類型里。如果你覺得麻煩同時想讓頭文件變得更加簡潔,你就會使用到審查區域。 ## 審查區域(Audited Regions) 如果想更加輕松的添加這些注解,那么你可以把Objective-C頭文件的某個區域標記為需要審查(for nullability),在這個區域內,所有簡單的指針類型都會被當作`nonnull`,我們之前的例子會變成這樣: ~~~ NS_ASSUME_NONNULL_BEGIN @interface AAPLList : NSObject <NSCoding, NSCopying> //--- - (nullable AAPLListItem *)itemWithName:(NSString *)name; - (NSInteger)indexOfItem:(AAPLListItem *)item; @property (copy, nullable) NSString *name; @property (copy, readonly) NSArray *allItems; //--- @end NS_ASSUME_NONNULL_END // -------------- self.list.name = nil; // okay AAPLListItem *matchingItem = [self.list itemWithName:nil]; // warning! ~~~ > Xcode 6.3(iOS 8.3 SDK)引入了`NS_ASSUME_NONNULL_BEGIN / END`宏? > 其中itemWithName方法的name參數沒有使用Nullability特征,但是會被當作`nonnull`處理 為了安全起見,這個規則也有一些例外情況: * `typedef`定義的類型不會繼承`nullability`特性—它們會輕松地根據上下文選擇nullable或non-nullable,所以,就算是在審查區域內,`typedef`定義的類型也不會被當作`nonnull`。 * 像`id *`這樣更復雜的指針類型必須被顯式地注解,比如,你要指定一個nonnull的指針為一個nullable的對象引用,那么需要使用`__nullable id * __nonnull`。 * 像`NSError **`這些特殊的、通過方法參數返回錯誤對象的類型,將總是被當作是一個nullable的指針指向一個nullable的指針:`__nullable NSError ** __nullable`。 你可以通過[Error Handling Programming Guide](http://developer.apple.com/go/?id=error-handling-cocoa)了解更多詳細內容。 ## 兼容性 你的Objective-C框架現有的代碼寫對了嗎?是否能安全的改變它們的類型??*Yes, it is*. * 現有的、被*編譯過*的代碼還能繼續使用你的框架,也就是說[ABI](https://developer.apple.com/library/ios/documentation/Xcode/Conceptual/iPhoneOSABIReference/Introduction/Introduction.html)沒有變化(編譯器不會報錯),這也意味著現有的代碼不會在運行時捕獲到`nil`的不正確傳值。 * 用新的Swift編譯器編譯現有的*源碼*,并在使用你的框架的時候,可能會因為一些不安全的行為在編譯時得到額外的警告。 * `nonnull`不影響優化,尤其是你還可以在運行時檢查標記為`nonnull`的參數是否為`nil`,這可能需要必要的向后兼容。 大多數情況下,應該接受`nullable`和`nonnull`,你當前所使用的斷言或者異常太粗暴了:違反約定是程序員經常犯的錯誤(而`nullable`和`nonnull`能在編譯時就解決問題)。特別的,返回值是你能控制的東西,永遠不應該對一個non-nullable的返回類型返回一個`nil`,除非這是為了向后兼容。 ## 回到Swift 現在我們給我們的Objective-C頭文件添加了nullability注解,我們在Swift中使用它:? 在Objective-C中添加注解之前: ~~~ class AAPLList : NSObject, NSCoding, NSCopying { //--- func itemWithName(name: String!) -> AAPLListItem! func indexOfItem(item: AAPLListItem!) -> Int @NSCopying var name: String! { get set } @NSCopying var allItems: [AnyObject]! { get } //--- } ~~~ 添加注解之后: ~~~ class AAPLList : NSObject, NSCoding, NSCopying { //--- func itemWithName(name: String) -> AAPLListItem? func indexOfItem(item: AAPLListItem) -> Int @NSCopying var name: String? { get set } @NSCopying var allItems: [AnyObject] { get } //--- } ~~~ 這些Swift代碼非常清晰。只有一些細節的變化,但是它讓你的框架使用起來更爽。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看