-
1.文件引用
(1)OC项目创建swift文件时,xcode询问是否创建XXX-Bridging-Header文件,确定创建.
(2)在targets - build setting - packaging中设置Defines Module为YES,同一栏里面的product name需要是项目名称.
setting
(3)在Bridging-Header文件中import OC头文件,swift文件里就可以访问该OC文件了.
Bridging-Header
tset.swift
(4)完成12步之后OC文件内#import <GOLAXY-Swift.h>,OC文件就可以访问该swift文件了,#import <GOLAXY-Swift.h>可以写在pch文件中
-
2.文件和方法名
有这样一个OC类
@interface MyObject : NSObject
+ (instancetype _Nonnull )object;
@end
@implementation MyObject
+ (instancetype)object
{
MyObject *logic = [[self alloc] init];
return logic;
}
在swift类中调用+objec方法时会报错
image.png
如果一个OC的类方法的方法名是类的最后一个单词,那么在swift中就无法使用.这个问题在纯swift中不会发生
-
3.获取class
OC代码从storyboard中初始化VC
NSString *className = NSStringFromClass(newClass);
[[UIStoryboard storyboardWithName:storyboardName bundle:nil]instantiateViewControllerWithIdentifier:className]
这个方法,当OC调用时,传入类名.class,于是className就是"类名"
在swift中,由于存在命名空间,当调用时,不管传入self(类方法中),或者类名.self,或者类名.classForCoder() 得到的className都是"包名.类名" ,需要切割字符串来适应原有的代码逻辑
-
4.在swift中使用+load和+initialize方法
原文
(1)定义一个协议
@protocol NSSwiftyLoadProtocol <NSObject>
@optional
+ (void)swiftyLoad;
+ (void)swiftyInitialize;
@end
(2)写一个宏用来为类生成分类,并且实现NSSwiftyLoadProtocol协议的方法
#define SWIFTY_LOAD_INITIALIZE(className) \
@interface className(swizzle_swifty_hook)\
@end\
\
@implementation className(swizzle_swifty_hook)\
+ (void)load {if ([[self class] respondsToSelector:@selector(swiftyLoad)]) {[[self class] swiftyLoad];}}\
+ (void)initialize {if ([[self class] respondsToSelector:@selector(swiftyInitialize)]) {[[self class] swiftyInitialize];}}\
@end
(3)把需要调用+load和+ (void)initialize方法的类,用宏来生成分类
#import <Foundation/Foundation.h>
#import <GOLAXY-Swift.h>
//添加需要重写+load或者+initialize的swift类
SWIFTY_LOAD_INITIALIZE(GLCourseListVC)
//...更多的类
(4)在swift类中调用
extension GLCourseListVC : NSSwiftyLoadProtocol{
public static func swiftyLoad() {
///code
}
}
-
5.swift和OC的互相访问
(1)只要宏定义中涉及OC的方法,swift文件里肯定是编译不了的,只能在swift中再定义一次,swift中的宏其实就是全局变量;
纯字符串的宏在swift文件也可以使用,不过这种我一般定义为静态字符串,不用define
/* theme */
//.h
extern NSString *const __nonnull GLTextBlack;
extern NSString *const __nonnull GLTextWhite;
//.m
NSString * const GLTextBlack = @"222222";
NSString * const GLTextWhite = @"dddddd";
这种定义在OC和swift中都可以使用;
(2)OC文件中的东西在swift中基本都可以用,只是需要按照swift的语法来写,但是swift中的全局变量在OC中是用不了的,只有@objc修饰的才可以在在OC文件中使用
@objc class TestClass:NSObject{
}
@objc修饰的类需要继承NSObject,并且@objc可以省略
@objc protocol TestProtocol{
@objc optional func testFunc()
}
@objc修饰的协议只能由OC类来遵循,swift类,结构体,枚举都不能遵循这种协议
并且方法也需要用@objc修饰,两边都得要,协议没加@objc的时候方法也不能加
@objc enum TestEnum:Int{
case TestEnumaa = 0
case TestEnumbb = 1
}
@objc 修饰的枚举,rawValue必须是Int类型
@objc class TestClass:NSObject{
@objc func test(){
}
}
extension TestClass{
@objc func extest(){
}
}
对于方法,不管是类的还是扩展的都必须用@objc修饰
@objc var pur : (() -> ())?
swift的属性也需要加@objc才能在OC文件中访问,并且添加@objc后不影响swift文件的访问
class ExampleClass: NSObject {
@objc var enabled: Bool {
@objc(isEnabled) get {
}
}
}
这段代码是给OC提供一个enabled属性的getter叫isEnabled
6.swift使用#if DEBUG
首先OC中能够使用#if DEBUG需要设置
需要有debug=1,一般默认就有
另外下面的release栏不要加,不然失去了意义
然后在swift中也能使用#if DEBUG需要设置,同样只设置debug
image.png
image.png
网友评论