Swift和Objective-C 混编注意事项
swift和objective-c 混编注意事项整理:
前言
swift已推出数年,与objective-c相比swift的语言机制及使用简易程度上更接地气,大大降低了ios入门门槛。当然这对新入行的童鞋没来讲,的确算是福音,但对于整个ios编程从业者来讲,真真是,曾几何时“高大上”,转瞬之间“矮矬穷”。再加上培训班横行,批量批发之下,ios再也看不到当年的辉煌。ios10推出后,紧跟着xcode8也推送了更新,细心者会发现,xcode8下ios版本最低适配已变为ios8.0,加上swift版本趋于稳定,从某种意义上讲,swift的时代正式开启,替代objective-c怕也只是时间问题。当然,在这之前,我们也应做好准备。今年越来的越多的公司,也开始了swift和objective-c混编。
我们今天就来看看两者混编中的一些注意事项及问题:
混编
混编也无非两种情况,
在objective - c工程或者文件使用swift的文件;
在swift工程或者文件使用objective - c文件。
在混编的过程中最重要的两个文件:
1.桥接文件
桥接文件“projectname-bridging-header.h”,在首次创建其他文件的时候,会自动生成。如果不小心删除后,也可以手动添加,不过名字必须是“projectname-bridging-header.h”头文件(名称组成:工程名-bridging-header.h),如果名字记不清也可以自己新建header file后,在targets→build settings→swift compiler - general→objective-c bridging header配置文件路径,这个文件主要是swift使用oc类时使用。
2.objective-c generated interface header name文件
这个文件是混编时,系统生成的swift文件对应的objective-c的头文件,具体可以在targets→build settings→swift compiler - general→objective-c generated interface header name进行配置,默认文件名是工程名-swift.h,一般不做改动。
在objective - c工程或者文件使用swift的文件
当在oc文件中调用swift文件中的类的时候,首先在oc文件中要加上 #import “
projectname-swift.h”(名字组成:工程名-swift)
这个文件虽然在工程中看不到,但是她真实存在,编译后,你可以按住command+单击该文件名,就会看到具体生成的代码。
引入后,具体类的使用,直接按照oc的方式使用即可。
在swift工程或者文件使用objective - c文件
当在swift中使用oc文件的时候,只需在桥接文件即projectname-bridging-header.h文件中引入需要的头文件。
具体使用,按照对应的swift语法结构来即可。
混编注意事项
对于需要混编的swift类添加@objc声明或继承nsobject或nsobject的子类
class testclass { // 属性 // 实现 }
如果要在objective-c类中使用testclass类,应当使用@objc加以声明,或者将testclass继承自nsobject或nsobject的子类,否则,引入productname-swift.h之后,程序找不到对应类。
使用第三方framework
设置: target-->build setting -->packaging -->defines module为 “yes”;
然后,配置文件target -> build phases -> link binary,添加要导入的framework;
最后,还是要配置桥接文件,比如要使用 abc-lib.framework库中的 abc.h 就要这样配置:#import"abc-lib/abc.h";
subclass子类问题
对于自定义的类而言,objective-c的类,不能继承自swift的类,即要混编的oc类不能是swift类的子类。反过来,需要混编的swift类可以继承自oc的类。 注解
oc宏文件
如swift文件要使用oc中定义的宏,只能使用常量简单宏文件。
swift独有特性
swift中有许多oc没有的特性,比如,swift有元组、为一等公民的函数、还有特有的枚举类型。所以,要使用的混编文件要注意swift独有属性问题。
案例之swift中使用oc的block
swift中使用closure不能使用block作为属性进行传值,必须是初始化方法或函数。
objective-c文件中:
#import <uikit/uikit.h> typedef void (^myblock)(nsstring *arg); @interface firviewcontroller : uiviewcontroller //@property (copy, nonatomic) myblock myblock; //这种作为公共参数的形式,如果在swift类中去回调的话,是有问题的。提示没有初始化方法,所以使用下面的以block为参数的方法 - (void)transvalue:(myblock) block; @end
下面是.m文件
#import "firviewcontroller.h" @implementation firviewcontroller - (void)viewdidload { [super viewdidload]; self.view.backgroundcolor = [uicolor whitecolor]; } - (void)transvalue:(myblock)block { if (block) { block(@"firback"); } } @end
在swift文件回调:
在swift使用oc的类时,首先在桥接文件中声明oc的头文件
工程名-bridging-header.h这是创建swift工程的情况下
import uikit class viewcontroller: uiviewcontroller { override func viewdidload() { super.viewdidload() self.view.backgroundcolor = uicolor.whitecolor() } @iboutlet weak var gofirst: uibutton! @ibaction func gofirstaction(sender: anyobject) { let firvc:firviewcontroller = firviewcontroller() firvc. transvalue { ( arg:string !) -> void in self.abtn?.settitle(arg, forstate: uicontrolstate.normal) } self.navigationcontroller?.pushviewcontroller(firvc, animated: true) }
swift和objective-c语言的混编就分享这么多,希望大神给出宝贵的意见!(@。ε。@)
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!