IOS --- OC与Swift混编

swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编。这个在IOS8中是允许的。
先中简单的入手,先研究在同一个工程目录下混合使用的情况。
为了演示。先准备两个类
第一个是swift语言写的类,文件名为 act.swift

[cpp] view plaincopy--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 1px; left: 2px;">--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 2px; left: 2px;">

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--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 1px; left: 2px;">--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 2px; left: 2px;">

import

@interface OCChannel : NSObject

@property (nonatomic,retain) NSString *ChannelName;

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

@end

实现文件

[cpp] view plaincopy--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 1px; left: 2px;">--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 2px; left: 2px;">

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
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625210532781%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">
建好后工程:
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625210612640%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">
2.就是分别引入前面的两个类,咱先一个个来。因为建的是Swift,所以,咱先以Swift工程中引用OC文件进行一次混编
Swift中使用OC
首先Swift中不再使用头文件和.m文件的方式了。所以也不需要使用import ""来导入头文件。哪swift 如何能访问到OC的类声明的。
其实,swift也是需要使用头文件进行访问的,只不过不再需要使用显式的方式使用import进行导入。有两种方式来实现这个头文件的生成。
方式一:在一个全新的Swift,利用第一次新建提示的方式自动添加桥接头文件。
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625212720406%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625212749578%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">
--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">
点确定这后就会生成一个以的头文件。
建好后的工程:
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625213205218%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">
这里有一个地方需要注意的就是在targets->build settings ->Object-C Bridging Header 设为哪个桥接的头文件即可。
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625213511140%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">

经过上述步骤,桥接文件弄好了就可以
尽情的把想要在swift类中调用的OC头文件放使用import "" 写到这个桥接文件中吧。就像:

[cpp] view plaincopy--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 1px; left: 2px;">--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 2px; left: 2px;">

//
// 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
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625215132328%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625215322390%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">

好了,以上的设置后就完全满足了Swift使用OC写的类了。

[cpp] view plaincopy--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 1px; left: 2px;">--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 2px; left: 2px;">

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 的头文件就是根据这个来命名的。
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625221046796%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625221403546%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">
虽然你看图中有这个import "SwiftModule-swift.h"但你在整个工程中是找不到这个文件的,但可以使用CMD+ 鼠标点击可看这个头文件中的内容。
--- OC与Swift混编" action-data="http%3A%2F%2Fimg.blog.csdn.net%2F20140625221826765%3Fwatermark%2F2%2Ftext%2FaHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVuZ3NoOTk4%2Ffont%2F5a6L5L2T%2Ffontsize%2F400%2Ffill%2FI0JBQkFCMA%3D%3D%2Fdissolve%2F70%2Fgravity%2FCenter" action-type="show-slide" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%;">

这样,工程中如查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--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 1px; left: 2px;">--- OC与Swift混编" style="margin: 0px; padding: 0px; border: 0px none; list-style: none; max-width: 100%; position: relative; top: 2px; left: 2px;">

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.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容

  • 深入理解傅里叶变换Mar 12, 2017 这原本是我在知乎上对傅立叶变换、拉普拉斯变换、Z变换的联系?为什么要进...
    价值趋势技术派阅读 5,545评论 2 2
  • iOS开发中有时候不可避免的会使用到OC和Swift的混编,这时候就需要建立桥接文件连接不同语言的类库 最近项目中...
    丶Destinyxl阅读 15,459评论 16 27
  • 1、垂直对齐 如果你用CSS,则你会有困惑:我该怎么垂直对齐容器中的元素?现在,利用CSS3的Transform,...
    kiddings阅读 3,104评论 0 11
  • 舅辛亥迄今,无论关乎政治之行为,或个人私行,为无过誉,无过毁,则“始终不失书生本色”最为的评。世人颇视书生为贬辞,...
    思漱阅读 203评论 0 0
  • 优秀与羡慕: 做一个永远让别人羡慕的人。 做一个让自己羡慕自己的人。 让别人羡慕,是因为比别人优秀! 让自己羡慕,...
    叶伟锋阅读 581评论 0 1