1. 程式人生 > >OC與Swift混編

OC與Swift混編

可能 完全 模式 -c after 產生 addition 沒有 派生

轉:原文地址:http://blog.csdn.net/fengsh998/article/details/34440159

swift 語言出來後,可能新的項目直接使用swift來開發,但可能在過程中會遇到一些情況,某些已用OC寫好的類或封裝好的模塊,不想再在swift 中再寫一次,那就使用混編。這個在iOS中是允許的。

先中簡單的入手,先研究在同一個工程目錄下混合使用的情況。

為了演示。先準備兩個類

第一個是swift語言寫的類,文件名為 act.swift

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

頭文件

#import <Foundation/Foundation.h>

@interface OCChannel : NSObject

@property (nonatomic,retain) NSString *ChannelName;

- (NSString *)ChannelChange:(NSInteger) channels;

@end

實現文件

#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,利用第一次新建提示的方式自動添加橋接頭文件。

技術分享

技術分享

技術分享

點確定這後就會生成一個以<produceName-Bridging-Header.h>的頭文件。

建好後的工程:

技術分享

這裏有一個地方需要註意的就是在targets->build settings ->Object-C Bridging Header 設為哪個橋接的頭文件即可。

技術分享

經過上述步驟,橋接文件弄好了就可以

盡情的把想要在swift類中調用的OC頭文件放使用import "" 寫到這個橋接文件中吧。就像:

[cpp] view plain copy
  1. //
  2. // Use this file to import your target‘s public headers that you would like to expose to Swift.
  3. //MixDemo/MixDemo-Bridging-Header.h
  4. #import "OCChannel.h"


同樣的,當你知道這個swift搜索頭文件的關系後,就不需要再理會這個-Bridging-Header.h的文件了。完全可以手工建一個並取自己喜歡的名字。如:

方式二:

新建一個頭文件,名為:OCContainerHeader.h

技術分享技術分享

好了,以上的設置後就完全滿足了Swift使用OC寫的類了。

[cpp] view plain copy
  1. import UIKit
  2. class ViewController: UIViewController {
  3. override func viewDidLoad() {
  4. super.viewDidLoad()
  5. // Do any additional setup after loading the view, typically from a nib.
  6. //調用OC類
  7. var channel = OCChannel()
  8. println(channel.ChannelChange(10))
  9. println(channel.ChannelChange(2))
  10. }
  11. override func didReceiveMemoryWarning() {
  12. super.didReceiveMemoryWarning()
  13. // Dispose of any resources that can be recreated.
  14. }
  15. }


好了下面再來看一下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下來。就像下面:

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.

OC與Swift混編