• 初探swift语言的学习—Object-C与Swift混编


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

    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. mport 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 a nib. 
    8.  
    9. //调用OC类 
    10. var channel = OCChannel() 
    11. println(channel.ChannelChange(10)) 
    12. println(channel.ChannelChange(2)) 
    13.  
    14. override func didReceiveMemoryWarning() { 
    15. super.didReceiveMemoryWarning() 
    16. // Dispose of any resources that can be recreated. 
    17.  
    18.  
    19. }  

    好了下面再来看一下OC如何调用Swift写的类。(事实上,如果你是一比一抄我这个DEMO,哪么恭喜你,在以上你将编译不通过。因为我的OC类中引用了swfit 写的类,所以你要想运行,就必须把哪个Act 的类注释了才行。)

    OC如何调用Swift写的类

    OC要想使用,必须有头文件。而swift文件却没有头文件,所在咱们想必也需要产生一个头文件。但对于OC调用swift 的头文件比较特殊。因头文件里面的机制是自动生成的,在不熟悉的,不建议手写。

    哪如何产生这个头文件。(注意,系统设置的头文件,在工程中是看不到的。)

    产生步骤:

    选中targets->build settings ->packing->Product Module Name 中设置模块名,这个名称很重要 swift 的头文件就是根据这个来命名的。

    这样,工程中如查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.

  • 相关阅读:
    Blank page instead of the SharePoint Central Administration site
    BizTalk 2010 BAM Configure
    Use ODBA with Visio 2007
    Handling SOAP Exceptions in BizTalk Orchestrations
    BizTalk与WebMethods之间的EDI交换
    Append messages in BizTalk
    FTP protocol commands
    Using Dynamic Maps in BizTalk(From CodeProject)
    Synchronous To Asynchronous Flows Without An Orchestration的简单实现
    WSE3 and "Action for ultimate recipient is required but not present in the message."
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4966627.html
Copyright © 2020-2023  润新知