1. 程式人生 > >初探swift語言的學習筆記九(OC與Swift混編)

初探swift語言的學習筆記九(OC與Swift混編)

作者:fengsh998原文地址:http://blog.csdn.net/fengsh998/article/details/34440159轉載請註明出處如果覺得文章對你有所幫助,請通過留言或關注微信公眾帳號fengsh998來支援我,謝謝!

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

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

為了演示。先準備兩個類

第一個是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 "" 寫到這個橋接檔案中吧。就像:

//
//  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寫的類了。

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下來。就像下面:

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.


好吧,今天就寫到這裡,再研究一下framework之間的混編。。。。。

相關推薦

初探swift語言學習筆記(OCSwift)

作者:fengsh998原文地址:http://blog.csdn.net/fengsh998/article/details/34440159轉載請註明出處如果覺得文章對你有所幫助,請通過留言或關注微信公眾帳號fengsh998來支援我,謝謝!swift 語言出來後,可能新

C語言學習筆記——結構體共同體

一.資料型別 1.基本資料型別:char、int、short、long、float; 2.指標型別:char*、int*、short*; 3.構造型別:char[ ]、int[ ]、short[ ]; 二.用typedef說明一個新型別 typedef是C語言一

C語言學習筆記_5函式程式結構

/**************************************************************************** *第五章函式與程式結構 *****2016

OC C++ 導致的問題

object c cos alt idt tails blog fun 所有 src 最近項目中用到 std::function. 在導入頭文件的時候,發現問題總是報頭文件無法找到。但是我通過xcode 跳轉都能夠跳轉到對應的文件了 #include <strin

OCC++工程配置

新公司做室內地圖引擎,類似於百度地圖的這種,底層是C++ openGLES寫的一套介面,在這個基礎上需要進行OC的封裝,在這裡寫一些過程中需要注意的點; 先說幾個工程配置的問題: -ObjC的使用,在TARGETS-build settings-Linking- Other

R語言學習筆記(十七):data.table包中meltdcast函數的使用

eas table variable mil pat efault ast 函數 pre melt函數可以將寬數據轉化為長數據 dcast函數可以將長數據轉化為寬數據 > DT = fread("melt_default.csv") > DT

swift語言點評十-類型轉化檢查

cover class HA cit known check sco really expect 1、oc比較: -(BOOL) isKindOfClass: classObj判斷是否是這個類或者這個類的子類的實例 -(BOOL) isMemberOfClass: clas

go語言學習筆記(4)--容器字符串的基本概念

都是 empty 知識 nil 來講 java nbsp unicode ... 一、 Slice(切片) package main import ( "fmt" ) //切片,slice func main() { arr := [...]int{1,2,

python3語言學習筆記(四:迭代器生成器)

迭代器(iterator)------一種物件 迭代是Python最強大的功能之一,是訪問集合元素的一種方式。 迭代器是一個可以記住遍歷的位置的物件。 迭代器物件從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。 迭代器有兩個基本的方法:iter() 和

Linux學習筆記(演算法資料結構)之 佇列程式碼(C語言

1、程式碼在VS2010的C++編譯器中編譯通過,可能有極少部分語法不符合C89標準;bool型別無法使用,用int代替 2、由於VS配置問題,沒有分.c和.h檔案書寫;如果要分,最好將Create_Node和Destory_Node加上static關鍵字修飾,他們只會在所

Linux學習筆記(演算法資料結構)之 二叉搜尋樹程式碼(C語言

1、程式碼在VS2010的C++編譯器中編譯通過,可能有極少部分語法不符合C99標準;bool型別無法使用,用int代替 2、由於VS配置問題,沒有分.c和.h檔案書寫;如果要分,最好將Create_Node和Destory_Node加上static關鍵字修飾,他們只會在所

《C語言程式設計:現代方法(第2版)(K.N.King 著)》學習筆記:格式化輸入/輸出(2)

3.2 scanf 函式 就如同 printf 函式用特定的格式顯示輸出一樣,scanf 函式也根據特定的格式讀取輸入。像 printf 函式的格式串一樣,scanf 函式的格式串也可以包含普通字元

go語言學習筆記--陣列切片

一、陣列 基本概念 1、一組相同型別已編號且長度固定的資料項序列 宣告格式:var identifier [len]type 2、Go語言中陣列是一種值型別,不是c中指向首元素地址,函式中使用 陣列作為引數,是值傳遞,會產生一次陣列拷貝。不會修改原資料 3、將陣列傳

R語言學習筆記之set.seed()函式table函式

set.seed(123)函式,此函式作用是為了,但你需要使用隨機數時,可保證你在執行或者除錯後,計算機所創造的隨機數保持不變。換句話說,如果使用隨機函式rnorm(10)之類的函式,每次執行後,結果都是不一樣的,如果再次之前使用set.seed()函式,則會保證測試資料保持

【R語言學習筆記】RGraphviz包的安裝載入方法

      最近學習一個演算法,是用R語言實現的,其中需要用到RGraphviz,我原先想按照以前安裝包的方法:在映象中找到就可以直接點選、安裝該包。可是我找遍了不同地區的一些映象,都找不到我想要安裝的包。所以我查詢資料,試了很多方法,最後成功了

C語言學習筆記---好用的函式memcpymemset

這個主要用於我個人的學習筆記,便於以後查詢,順便分享給大家。 想必在用C的時候難免會與陣列,指標,記憶體這幾樣東西打交道,先以陣列為例,例如有一個數組int a[5] = {1, 2, 3, 4, 5},我們要將陣列a裡面的資料複製到陣列b中,一般剛剛接觸C語言的我們會怎麼做?我們一般會想到用迴圈來做吧

GO語言學習筆記(二)IDE安裝配置、格式化代碼、生成代碼文檔

dea mit sts eid mark idea current href alt 一、安裝goland IDE1、goland IDE的下載 下載地址:(我這裏是下載的mac版,因為我的是mac本)https://download-cf.jetbrains.com/g

Go語言學習筆記----C語言的比較學習

最近學習了golang(go語言),其中大部分是和C相似的,記錄一下不同的地方,需要注意 1.go的左花括號“{”不能單獨放在一行 出錯程式碼: package main import "fmt" func main() { //error, ca

C語言學習筆記)—— 函式、遞迴和指標

一、函式1、一個簡單的函式示例函式是完成特定任務的獨立程式程式碼單元。#include <stdio.h> void printStar();//宣告函式原型,函式原型會指明函式的型別和函式接受的引數。前面的void是函式型別,表明函式沒有返回值 #define

Linux學習筆記:磁盤分區文件系統

方式 默認 label 掛載設備 文件的 gdisk part 生成 grub.con disk partitions & filesystem ---磁盤分區與文件系統--- 分區 磁盤分區方法:主流MBR & GPT parted fdisk:2T以內