1、创建桥接文件
在创建另一种语言的文件时xcode会提示创建项目名-bridging-header.h的桥接文件
2、swift调用oc
1.创建oc文件
#import "myviewcontroller.h" @interface myviewcontroller () @end @implementation myviewcontroller - (void)viewdidload { [super viewdidload]; self.title = @"oc"; self.view.backgroundcolor = uicolor.cyancolor; uilabel *lbl = [uilabel new]; lbl.text = @"oc的标签"; lbl.backgroundcolor = uicolor.redcolor; lbl.frame = cgrectmake(100, 100, 150, 50); [self.view addsubview:lbl]; }
2.桥接文件:项目名-bridging-header.h 文件中要将想要使用的 oc的.h文件导入
#import "myviewcontroller.h"
3.在swift文件中调用
import uikit class viewcontroller: uiviewcontroller { override func viewdidload() { super.viewdidload() // do any additional setup after loading the view. title = "swift" view.backgroundcolor = .white let btn = uibutton(type: .custom) btn.frame = cgrect(x: 150, y: 150, width: 150, height: 100) btn.settitle("点击跳转", for: .normal) btn.backgroundcolor = .green view.addsubview(btn) btn.addtarget(self, action: #selector(didclickbtn), for: uicontrol.event.touchupinside) } @objc func didclickbtn() { let myvc = myviewcontroller() navigationcontroller?.pushviewcontroller(myvc, animated: true) } }
button执行的方法要用 @objc 修饰
ns_swift_name、ns_swift_unavailable
- ns_swift_name(替换名):重命名在swift中的名称,可用来进行方法名隐藏
- ns_swift_unavailable(_msg):swift中不可见,不能使用
// oc的myviewcontroller.h文件 #import <uikit/uikit.h> ns_assume_nonnull_begin @interface myviewcontroller : uiviewcontroller // 将method1方法在swift中替换成swiftmethod()方法 - (void)method1 ns_swift_name(swiftmethd()); // 将method2方法再swift中隐藏 - (void)method2 ns_swift_unavailable("swift中该方法不可调用"); @end ns_assume_nonnull_end
class viewcontroller: uiviewcontroller { override func viewdidload() { ...... } @objc func didclickbtn() { let myvc = myviewcontroller() // 在swift中找不到oc的method1与method2方法,只有一个改了名的swiftmethod方法 myvc.swiftmethod() navigationcontroller?.pushviewcontroller(myvc, animated: true) } }
ns_refined_for_swift
在swift中调用oc的接口有时发现并不符合swift的语法规范或者使用起来会比较别扭,这个时候可以使用ns_refined_for_swift宏定义 来对oc的接口进行升级改造
规则
ns_refined_for_swift 可用于方法和属性,添加了 ns_refined_for_swift 的 objective-c api 在导入到 swift 时,具体的 api 重命名规则如下:
对于 初始化方法,在其第一个参数标签前面加 "__"
// objective-c api - (instancetype)initwithclassname:(nsstring *)name ns_refined_for_swift; // in swift init(__classname: string)
对于 其它方法,在其基名前面加 "__"
// objective-c api - (nsstring *)displaynameformode:(displaymode)mode ns_refined_for_swift; // in swift func __displaynameformode(mode: displaymode) -> string
下标方法将被视为任何其它方法,在方法名前面加 "__"(而不是作为 swift 下标导入)
其他声明将在其名称前加上 "__",例如属性
// objective-c api @property displaymode mode ns_refined_for_swift; // in swift var __mode: displaymode { get set }
注意:ns_refined_for_swift 和 ns_swift_name 一起用的话,ns_refined_for_swift 不生效,而是以 ns_swift_name 指定的名称重命名 objective-c api
3、oc调用swift
创建swift文件
import foundation // 必须继承于 nsobject class person: nsobject { // 想公开给oc的要使用 @objc 修饰 @objc var name: string @objc var age : int @objc init(name: string, age: int) { self.name = name self.age = age } }
- 必须继承于 nsobject,类、结构体等才会公开给oc
- 必须使用 @objc 修饰,属性、方法等才会公开给oc
在swift文件中引入项目名-swift.h文件,然后使用swift内容
#import "myviewcontroller.h" #import "swiftandoc-swift.h" @interface myviewcontroller () @end @implementation myviewcontroller - (void)viewdidload { [super viewdidload]; person *p = [[person alloc] initwithname:@"lz" age:18]; nslog(@"%@",p.name); }
4、坑点
- oc类不能继承于swift类,但swift类可以继承于oc类
- swift中没有宏定义:
常量宏用let参数代替
无参变量宏可以用"只读属性"代替也可用函数代替
变量宏用函数代替
- 要给oc用的内容不要用swift独有特性书写(比如元组)
- 如果oc通过pod的形式集成swift,需要在 swift的类上也要声明public,否则在对应的 项目名-swift.h 上不会有对应的类出现
以上就是ios开发swift 与 oc相互调用详解的详细内容,更多关于swift oc相互调用的资料请关注代码网其它相关文章!
发表评论