加载中…
正文 字体大小:

IOS --- OC与Swift混编

(2014-10-30 16:02:11)
群里大神发的网址,感觉有用就先收录了,暂时没时间看SWIFT,感觉代码简洁,但是可阅读性不是太高,有些代码让系统去判断类型,同样的,我们看代码的时候也得自己去判断类型,或许看多就习惯了,有时间再说吧,swift一时半会儿也没法写进程序里

作者:fengsh998
原文地址:http://blog.csdn.net/fengsh998/article/details/34440159
转载请注明出处
如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号fengsh998来支持我,谢谢!

 


swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编。这个在IOS8中是允许的。

先中简单的入手,先研究在同一个工程目录下混合使用的情况。

为了演示。先准备两个类

第一个是swift语言写的类,文件名为 act.swift

 

  1. import Foundation  
  2.   
  3. class Act NSObject  
  4.  
  5.     func hasAct(tag:Int) -> String  
  6.      
  7.         switch (tag)  
  8.          
  9.         case 1:return "Movie"  
  10.         case 2:return "CCTV"  
  11.         case 3:return "Sport TV"  
  12.         default:return "Area TV"  
  13.          
  14.      
  15.       
  16.     init()  
  17.      
  18.         println("act constructor is called." 
  19.      
  20.       
  21.     deinit  
  22.      
  23.         println("act destroyed is called." 
  24.      
  25.  

 

第二个是用OC写的类 头文件为OCChannel.h ,实现文件为OCChannel.m

头文件

 

  1. #import   
  2.   
  3. @interface OCChannel NSObject  
  4.   
  5. @property (nonatomic,retain) NSString *ChannelName;  
  6.   
  7. (NSString *)ChannelChange:(NSInteger) channels;  
  8.   
  9. @end  

实现文件

 

 

  1. #import "OCChannel.h"  
  2. #import "SwiftModule-swift.h"  
  3.   
  4. @interface OCChannel()  
  5.  
  6.     Act     *act;  //swift的类  
  7.  
  8. @end  
  9.   
  10. @implementation OCChannel  
  11.   
  12. (id)init  
  13.  
  14.     if (self [super init])  
  15.         NSLog(@"OC Constructor is called.");  
  16.         //使用Swift类  
  17.         act [[Act alloc]init];  
  18.      
  19.     return self;  
  20.  
  21.   
  22. (void)dealloc  
  23.  
  24.     NSLog(@"OC Destroyed is called.");  
  25.     //[act release];//ARC not use  
  26.     //[super dealloc];//ARC not use  
  27.  
  28.   
  29. (NSString *)ChannelChange:(NSInteger) channels  
  30.  
  31.     return [act hasAct:channels];  
  32.  
  33.   
  34. @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 "" 写到这个桥接文件中吧。就像:

 

  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.   
  5. #import "OCChannel.h"  

同样的,当你知道这个swift搜索头文件的关系后,就不需要再理会这个-Bridging-Header.h的文件了。完全可以手工建一个并取自己喜欢的名字。如:

 

方式二:

新建一个头文件,名为:OCContainerHeader.h



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

 

  1. import UIKit  
  2.   
  3. class ViewController: UIViewController  
  4.                               
  5.     override func viewDidLoad()  
  6.         super.viewDidLoad()  
  7.         // Do any additional setup after loading the view, typically from nib.  
  8.   
  9.         //调用OC类  
  10.         var channel OCChannel()  
  11.         println(channel.ChannelChange(10))  
  12.         println(channel.ChannelChange(2))  
  13.      
  14.   
  15.     override func didReceiveMemoryWarning()  
  16.         super.didReceiveMemoryWarning()  
  17.         // Dispose of any resources that can be recreated.  
  18.      
  19.   
  20.   
  21.  

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

 

 

  1. import Foundation  
  2.   
  3. @objc(Act)  
  4.   
  5. class Act   
  6.  
  7.     func hasAct(tag:Int) -> String  
  8.      
  9.         switch (tag)  
  10.          
  11.         case 1:return "Movie"  
  12.         case 2:return "CCTV"  
  13.         case 3:return "Sport TV"  
  14.         default:return "Area TV"  
  15.          
  16.      
  17.   
  18.     @objc(init)//原本以为加上这个alloc就可以找到,但不行的。。。  
  19.     init()  
  20.      
  21.         println("act constructor is called." 
  22.      
  23.       
  24.     deinit  
  25.      
  26.         println("act destroyed is called." 
  27.      
  28.  

但是在使用时你就会发现

 

        act = [[Act alloc]init]; //报错,找不到alloc,因此建议大家还是继承NSObject.

0

阅读 评论 收藏 转载 喜欢 打印举报
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有