0、导入头文件。
oc类使用swift类,必须导入头文件appname-swift.h,该文件不可见,但可以点进去。swift调用oc类,必须在文件appNme-Bridging-Header.h中导入oc类的头文件。
1、swift类可以继承oc类,oc类不能继承swift类(即使该swift类的父类是oc类也不行)。
如,创建一个oc类OCObj
OCObj.h:
#import <Foundation/Foundation.h>
@class SubOfNSObj;
@class NotSubNSObj; //HB2-Swift.h里没有
@interface OCObj : NSObject
//@property (nonatomic, copy) NSString * _Nullable name;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString * _Nullable name2;
@end
OCObj.m
#import "OCObj.h"
@implementation OCObj
@end
创建一个继承于NSObject的swift类:
class SubOfNSObj: NSObject {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
}
创建一个没有父类的swift类:
class NotSubNSObj {
let name: String
let age: Int
init(name: String, age: Int) {
self.name = name
self.age = age
}
//swift可以使用oc的类
func testOCObj() {
let ocObj = OCObj()
ocObj.name = "张三"
let name1: String = ocObj.name
let name2: String = ocObj.name2!
print(name1)
print(name2)
}
}
创建一个继承于OCObj的swift类:
class SwiftTestClass: OCObj {
//swift类可以继承oc类,oc不能继承swift类
}
如果强行创建一个oc类继承于swift类:
//swift类可以继承oc类,oc不能继承swift类。如果直接创建oc文件,可以选择swift类作为父类,但创建后会报错。
//@interface OCObjTestSubSwift : SubOfNSObj
////错误:Attempting to use the forward class ......
//@end
2、oc类在使用swift类时,该swift类必须继承于oc类。
如,在oc类ViewController中使用时:
- (void)test
{
SubOfNSObj *obj1 = [[SubOfNSObj alloc] initWithName:@"lisi" age:4];
NSLog(@"%@", obj1.name);
//没有继承nsobject的swift类不能在oc中使用
// NotSubNSObj *obj1 = [NotSubNSObj new];//use of undeclaerd identifier 'NotSubNSObj'
}
3、swift中没有宏,可以使用全局常量、全局函数代替部分宏。
swift中是不能使用宏定义语法,但是因为命名空间的缘故,在其中,我们将原本oc中不需要接受参数的宏,定义成let常量或枚举,将需要接受参数的宏定义成函数。
⚠️横屏后kScreenHeight及kScreenWidth是不会变化的,因为是常量,只会赋值一次。OC中则会实时变化,因为不是赋值,是宏替换。
⚠️ 这里定义的常量oc中并不能使用,可以定义一个类,然后将所有的全局变量和常量改成这个类的属性。
如oc中常用的几个宏:
#define kIOS7 [UIDevice currentDevice].systemVersion.doubleValue>=7.0 ? 1 :0
#define kIOS8 [UIDevice currentDevice].systemVersion.doubleValue>=8.0 ? 1 :0
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
在swift中定义为全局常量:
let kIOS7 = Double(UIDevice().systemVersion)! >= 7.0 ? 1 : 0
let kIOS8 = Double(UIDevice().systemVersion)! >= 8.0 ? 1 : 0
let kSCREEN_HEIGHT = UIScreen.main.bounds.height
let kSCREEN_WIDTH = UIScreen.main.bounds.width
定义成枚举、全局函数举例:
//MARK:时间格式:
enum TimeFormat: String {
case common = "yyy-MM-dd HH:mm:ss"
case yyMdHm = "yy-MM-dd HH:mm"
}
/MARK:沙盒路径
//Documnets目录
func pathForDocument() -> String {
let ducumentPath = NSHomeDirectory() + "/Documents"
return ducumentPath
}
使用:
let timeFormatStr = TimeFormat.yyMdHm.rawValue
let formatter = DateFormatter();
formatter.dateFormat = timeFormatSt
let timeStr = formatter.string(from: Date())
print(timeStr)
let path = pathForDocument()
print(path)
4、swift枚举类型在oc中使用
如果需要在oc类中使用时只能使用带@objc的枚举,带@objc的枚举必须时Int类型,否则会报错。
enum Direction {
case Up
case Down
case Left
case Right
}
enum Direction2: Int {
case Up2
case Down2
case Left2
case Right
@objc enum Direction3: Int {
case Up3
case Down3
case Left3
case Right3
}
以上三个枚举,只有Direction3能在oc类中使用, Direction、Direction2都不能在oc类中使用。
5、swift中使用oc的NS_OPTIONS类型枚举
swift中没有“|”,
如,下面写法是错误的
let options : NSStringDrawingOptions = .UsesLineFragmentOrigin | .UsesFontLeading
比较蹩脚的解决办法:
创建OC类,类中定义个方法,然后在swift的调用这个方法。
(注:swift中与NS_OPTIONS相似的是struck实现 OptionSet 协议。)
6、oc使用swift定义的协议
//如果要在oc中使用swift定义的协议,则需要加上@objc,且如果是不必实现的函数,函数前要加上 @objc optional。
如:
@objc protocol AlertViewProtocol {
func didSelect(_ row: Int) //必须实现的协议
@objc optional func onPickerCancel() //不必实现的协议
@objc optional func showed()
}
7、其他swift中有而oc中没有的
1、元组:对于oc可能用到的:方法,返回不能是元组,参数能不能是元组。属性不能是元组。
2、范型(Generics)范型
3、Swift 中定义的结构体(Structures defined in Swift)不能在oc中使用,OC中必须继承nsobj
4、Swift 中定义的顶层函数(Top-level functions defined in Swift)
5、Swift 中定义的全局变量(Global variables defined in Swift)
6、Swift 中定义的类型别名(Typealiases defined in Swift)
7、Swift风格可变参数(Swift-style variadics)
8、嵌套类型(Nested types)
9、柯里化函数(Curried functions)
8、单例
swift创建单例比较方便、安全。
在swift写的模块中,Manager单例的代码如下
@objc public class Manager: NSObject {
public static let shared = Manager()
}
但这样写在oc模块中不能获取单例.
可以添加一个供oc调用的函数
@objc public class Manager: NSObject {
public static let shared = Manager()
@objc public static func sharedInstance() -> Manager {
return shared
}
}
oc中使用
Manager *training = [Manager sharedInstance];
(如有错误欢迎斧正)