成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Swift TIP之objc 和 dynamic

移動開發 iOS
雖然說 Swift 語言的初衷是希望能擺脫 Objective-C 的沉重的歷史包袱和約束,但是不可否認的是經過了二十多年的洗禮,Cocoa 框架早就烙上了不可磨滅的 Objective-C 的印記。無數的第三方庫是用 Objective-C 寫成的,這些積累無論是誰都不能小覷。因此,在最初的版本中,Swift 不得不考慮與 Objective-C 的兼容。

雖然說 Swift 語言的初衷是希望能擺脫 Objective-C 的沉重的歷史包袱和約束,但是不可否認的是經過了二十多年的洗禮,Cocoa 框架早就烙上了不可磨滅的 Objective-C 的印記。無數的第三方庫是用 Objective-C 寫成的,這些積累無論是誰都不能小覷。因此,在最初的版本中,Swift 不得不考慮與 Objective-C 的兼容。

Apple 采取的做法是允許我們在同一個項目中同時使用 Swift 和 Objective-C 來進行開發。其實一個項目中的 Objective-C 文件和 Swift 文件是處于兩個不同世界中的,為了讓它們能相互聯通,我們需要添加一些橋梁。

首先通過添加 {product-module-name}-Bridging-Header.h 文件,并在其中填寫想要使用的頭文件名稱,我們就可以很容易地在 Swift 中使用 Objective-C 代碼了。Xcode 為了簡化這個設定,甚至在 Swift 項目中第一次導入 Objective-C 文件時會主動彈框進行詢問是否要自動創建這個文件,可以說是非常方便。

但是如果想要在 Objective-C 中使用 Swift 的類型的時候,事情就復雜一些。如果是來自外部的框架,那么這個框架與 Objective-C 項目肯定不是處在同一個 target 中的,我們需要對外部的 Swift module 進行導入。這個其實和使用 Objective-C 的原來的 Framework 是一樣的,對于一個項目來說,外界框架是由 Swift 寫的還是 Objective-C 寫的,兩者并沒有太大區別。我們通過使用 2013 年新引入的 @import 來引入 module:

 

  1. @import MySwiftKit; 

之后就可以正常使用這個 Swift 寫的框架了。

如果想要在 Objective-C 里使用的是同一個項目中的 Swift 的源文件的話,可以直接導入自動生成的頭文件 {product-module-name}-Swift.h 來完成。比如項目的 target 叫做 MyApp 的話,我們就需要在 Objective-C 文件中寫

 

  1. #import "MyApp-Swift.h" 

但這只是故事的開始。Objective-C 和 Swift 在底層使用的是兩套完全不同的機制,Cocoa 中的 Objective-C 對象是基于運行時的,它從骨子里遵循了 KVC (Key-Value Coding,通過類似字典的方式存儲對象信息) 以及動態派發 (Dynamic Dispatch,在運行調用時再決定實際調用的具體實現)。而 Swift 為了追求性能,如果沒有特殊需要的話,是不會在運行時再來決定這些的。也就是說,Swift 類型的成員或者方法在編譯時就已經決定,而運行時便不再需要經過一次查找,而可以直接使用。

顯而易見,這帶來的問題是如果我們要使用 Objective-C 的代碼或者特性來調用純 Swift 的類型時候,我們會因為找不到所需要的這些運行時信息,而導致失敗。解決起來也很簡單,在 Swift 類型文件中,我們可以將需要暴露給 Objective-C 使用的任何地方 (包括類,屬性和方法等) 的聲明前面加上 @objc 修飾符。注意這個步驟只需要對那些不是繼承自 NSObject 的類型進行,如果你用 Swift 寫的 class 是繼承自 NSObject 的話,Swift 會默認自動為所有的非 private 的類和成員加上 @objc。這就是說,對一個 NSObject 的子類,你只需要導入相應的頭文件就可以在 Objective-C 里使用這個類了。

@objc 修飾符的另一個作用是為 Objective-C 側重新聲明方法或者變量的名字。雖然絕大部分時候自動轉換的方法名已經足夠好用 (比如會將 Swift 中類似 init(name: String) 的方法轉換成 -initWithName:(NSString *)name 這樣),但是有時候我們還是期望 Objective-C 里使用和 Swift 中不一樣的方法名或者類的名字,比如 Swift 里這樣的一個類:

 

  1. class 我的類 { 
  2. func 打招呼(名字: String) { 
  3. println("哈嘍,\(名字)"

我的類().打招呼("小明")

Objective-C 的話是無法使用中文來進行調用的,因此我們必須使用 @objc 將其轉為 ASCII 才能在 Objective-C 里訪問:

 

  1. @objc(MyClass) 
  2. class 我的類 { 
  3. @objc(greeting:) 
  4. func 打招呼(名字: String) { 
  5. println("哈嘍,\(名字)"

這樣,我們在 Objective-C 里就能調用 [[MyClass new] greeting:@"XiaoMing"] 這樣的代碼了 (雖然比起原來一點都不好玩了)。另外,正如上面所說的以及在 Selector 一節中所提到的,即使是 NSObject 的子類,Swift 也不會在被標記為 private 的方法或成員上自動加 @objc。如果我們需要使用這些內容的動態特性的話,我們需要手動給它們加上 @objc 修飾。

添加 @objc 修飾符并不意味著這個方法或者屬性會變成動態派發,Swift 依然可能會將其優化為靜態調用。如果你需要和 Objective-C 里動態調用時相同的運行時特性的話,你需要使用的修飾符是 dynamic。一般情況下在做 app 開發時應該用不上,但是在施展一些像動態替換方法或者運行時再決定實現這樣的 "黑魔法" 的時候,我們就需要用到 dynamic 修飾符了。在之后的 KVO 一節中,我們還會提到一個關于使用 dynamic 的實例。
 

責任編輯:chenqingxiang 來源: swifter.tips
相關推薦

2015-02-05 00:18:44

SwiftObjective-C

2021-07-09 19:04:55

Cache查找消息

2015-08-25 14:25:54

objc_msgsen

2015-04-01 14:34:37

C#dynamicDictionary性

2009-05-25 15:42:03

Visual StudC#

2015-07-30 10:42:38

SwiftUIButton

2015-03-16 10:17:48

objc照片框架

2014-06-05 14:12:05

SwiftUI學習iOS

2024-01-15 08:39:12

ArraysSetsTypeScript

2019-03-26 08:15:45

iOS尾調用Objective-C

2011-12-29 15:35:39

Web

2011-01-14 13:40:24

UbuntuLinux Tips

2010-09-09 12:49:58

鼠標懸停tip效果CSS

2022-03-04 09:02:01

StoryBoard工具git

2009-10-27 11:08:25

C# 4.0dynamic

2010-12-03 12:16:49

2014-09-26 09:49:48

SwiftObjective-C

2025-03-19 09:02:18

Debouncing任務讓步Swift

2023-02-08 09:01:42

Swift元素流

2009-09-25 10:38:42

Hibernate動態
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕精品一区久久久久 | 久久久99国产精品免费 | 国产精品99精品久久免费 | 91福利在线观看视频 | 美国一级黄色片 | 精品免费国产视频 | 一区二区在线不卡 | 欧美男人天堂 | 999国产视频 | 精品二三区 | 日韩中文字幕网 | www.亚洲一区 | 国产欧美视频一区二区 | 成人影院在线 | 四色永久 | 国产精品一区二区视频 | 国产成人精品久久二区二区 | 久草在线免费资源 | 亚洲视频中文字幕 | 黄色片视频网站 | 中文字幕 视频一区 | 久久精品二区亚洲w码 | 成人欧美一区二区三区黑人孕妇 | 日韩欧美精品在线 | 国产精品乱码一区二区三区 | 欧美v在线观看 | h在线免费观看 | 欧美一级片在线看 | 黄色片免费| 欧美日韩国产在线观看 | 精品在线观看入口 | 日韩在线精品 | 精品一区二区三区不卡 | 国产欧美日韩一区二区三区在线 | 久久精品国产亚洲一区二区三区 | 久操av在线 | 久久精品小视频 | 成人国产精品入口免费视频 | 黄网免费| 中文字幕欧美一区 | 手机av在线 |