IOS --- OC與Swift混編

來源:互聯網
上載者:User

標籤:

swift 語言出來後,可能新的項目直接使用swift來開發,但可能在過程中會遇到一些情況,某些已用OC寫好的類或封裝好的模組,不想再在swift 中再寫一次,哪就使用混編。這個在IOS8中是允許的。 先中簡單的入手,先研究在同一個工程目錄下混合使用的情況。 為了示範。先準備兩個類 第一個是swift語言寫的類,檔案名稱為 act.swift   [cpp] view plaincopy在CODE上查看代碼片派生到My Code片 import Foundation    class Act : NSObject  {      func hasAct(tag:Int) -> String      {          switch (tag)          {          case 1:return "Movie"          case 2:return "CCTV"          case 3:return "Sport TV"          default:return "Area TV"          }      }            init()      {          println("act constructor is called.")      }            deinit      {          println("act destroyed is called.")      }  } 

  第二個是用OC寫的類 標頭檔為OCChannel.h ,實現檔案為OCChannel.m 標頭檔   [cpp] view plaincopy在CODE上查看代碼片派生到My Code片 #import     @interface OCChannel : NSObject    @property (nonatomic,retain) NSString *ChannelName;    - (NSString *)ChannelChange:(NSInteger) channels;    @end 

實現檔案     [cpp] view plaincopy在CODE上查看代碼片派生到My Code片 #import "OCChannel.h"  #import "SwiftModule-swift.h"    @interface OCChannel()  {      Act     *act;  //swift的類  }  @end    @implementation OCChannel    - (id)init  {      if (self = [super init]) {          NSLog(@"OC Constructor is called.");          //使用Swift類          act = [[Act alloc]init];      }      return self;  }    - (void)dealloc  {      NSLog(@"OC Destroyed is called.");      //[act release];//ARC not use      //[super dealloc];//ARC not use  }    - (NSString *)ChannelChange:(NSInteger) channels  {      return [act hasAct:channels];  }    @end 

這個OCChannel為中引用了swift 寫的類Act 。主要是為了示範在同一個工程項目裡,swift類調用OC,同時OC類也調用Swift。從而形成一種混合編寫的模式。  

下面是具體步驟: 1.建立一個Swift工程:我這裡工程名為MixDemo

建好後工程:

2.就是分別引入前面的兩個類,咱先一個個來。因為建的是Swift,所以,咱先以Swift工程中引用OC檔案進行一次混編 Swift中使用OC 首先Swift中不再使用標頭檔和.m檔案的方式了。所以也不需要使用import ""來匯入標頭檔。哪swift 如何能訪問到OC的類聲明的。 其實,swift也是需要使用標頭檔進行訪問的,只不過不再需要使用顯式的方式使用import進行匯入。有兩種方式來實現這個標頭檔的產生。 方式一:在一個全新的Swift,利用第一次建立提示的方式自動添加橋接標頭檔。

 

點確定這後就會產生一個以的標頭檔。 建好後的工程:

這裡有一個地方需要注意的就是在targets->build settings ->Object-C Bridging Header 設為哪個橋接的標頭檔即可。

經過上述步驟,橋接檔案弄好了就可以 盡情的把想要在swift類中調用的OC標頭檔放使用import "" 寫到這個橋接檔案中吧。就像:   [cpp] view plaincopy在CODE上查看代碼片派生到My Code片 //  //  Use this file to import your target‘s public headers that you would like to expose to Swift.  //MixDemo/MixDemo-Bridging-Header.h    #import "OCChannel.h" 

同樣的,當你知道這個swift搜尋標頭檔的關係後,就不需要再理會這個-Bridging-Header.h的檔案了。完全可以手工建一個並取自己喜歡的名字。如:   方式二: 建立一個標頭檔,名為:OCContainerHeader.h

好了,以上的設定後就完全滿足了Swift使用OC寫的類了。   [cpp] view plaincopy在CODE上查看代碼片派生到My Code片 import UIKit    class ViewController: UIViewController {                                    override func viewDidLoad() {          super.viewDidLoad()          // Do any additional setup after loading the view, typically from a nib.            //調用OC類          var channel = OCChannel()          println(channel.ChannelChange(10))          println(channel.ChannelChange(2))      }        override func didReceiveMemoryWarning() {          super.didReceiveMemoryWarning()          // Dispose of any resources that can be recreated.      }      } 

好了下面再來看一下OC如何調用Swift寫的類。(事實上,如果你是一比一抄我這個DEMO,哪麼恭喜你,在以上你將編譯不通過。因為我的OC類中引用了swfit 寫的類,所以你要想運行,就必須把哪個Act 的類注釋了才行。)  

OC如何調用Swift寫的類 OC要想使用,必須有標頭檔。而swift檔案卻沒有標頭檔,所在咱們想必也需要產生一個標頭檔。但對於OC調用swift  的標頭檔比較特殊。因標頭檔裡面的機制是自動產生的,在不熟悉的,不建議手寫。 哪如何產生這個標頭檔。(注意,系統設定的標頭檔,在工程中是看不到的。) 產生步驟: 選中targets->build settings ->packing->Product Module Name 中設定模組名,這個名稱很重要 swift 的標頭檔就是根據這個來命名的。

雖然你看圖中有這個import "SwiftModule-swift.h"但你在整個工程中是找不到這個檔案的,但可以使用CMD+ 滑鼠點擊可看這個標頭檔中的內容。

這樣,工程中如查Swift要使用OC,則把需要使用的OC類的標頭檔,全寫在MixDemo-Bridging-Header.h裡。同樣如果OC中所使用的swift類,只需要Clean一把,再編就可以了,但不要忘了匯入SwiftModule-swift.h哦(名稱自取,但-swift.h是固定的),另外還有一個需要讀者注意的。 註: 凡是用Swift寫的類,如果不繼成自NSObject或NSObject 的衍生類別,哪麼編譯後將不會產生對應的轉換類。從而使得OC 中找不到相應的聲明。 如我的例子中 class Act 這樣不會被編譯到SwiftModule-swift.h中,但寫為 class Act : NSObject,就可以編譯出相應的聲明。另外可以使用@objc加以聲明,但這個還是一樣,類最好繼承NSObject下來。就像下面:     [cpp] view plaincopy在CODE上查看代碼片派生到My Code片 import Foundation    @objc(Act)    class Act   {      func hasAct(tag:Int) -> String      {          switch (tag)          {          case 1:return "Movie"          case 2:return "CCTV"          case 3:return "Sport TV"          default:return "Area TV"          }      }        @objc(init)//原本以為加上這個alloc就可以找到,但不行的。。。      init()      {          println("act constructor is called.")      }            deinit      {          println("act destroyed is called.")      }  } 

但是在使用時你就會發現           act = [[Act alloc]init]; //報錯,找不到alloc,因此建議大家還是繼承NSObject.

IOS --- OC與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.