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相互调用的资料请关注代码网其它相关文章!
发表评论