美文网首页
OC调Swift的问题记录

OC调Swift的问题记录

作者: 桔子听 | 来源:发表于2018-02-02 17:32 被阅读739次

Swift调OC比较简单,之所以这么说,是因为Swift覆盖OC的大部分功能,即使有些没有覆盖,官方肯定也会给出解决方法。而OC相对于Swift而言,很多Swift特有的新功能OC是没有的,所以,OC可能在调用Swift的时候,会将Swift特有的功能引入OC,这个时候就会出错,因为,OC支持不了Swift的新功能。

OC调用Swift,需要先#import "工程名-swift.h"

1.如果Swift类没有继承自NSObject,那么OC不能调用,给类加上: NSObject。系统会给继承自NSObject的类,自动加上@objc修饰,除了private修饰的方法和属性。

2.不是继承自:NSObject的类,需要手动在方法或属性前加上@objc,Swift之后,即使是继承自:NSObject的类,也需要显式添加@objc才能访问。之前是默认添加的。

3.Swift中的枚举,OC中不能使用,OC中枚举实际都是Int型:

enum MethodType {
    case POST
    case GET
    case DELETE
}

改成:

@objc enum MethodType: Int {
    case POST
    case GET
    case DELETE
}

注意,要继承Int,加上@objc

5.在Swift中是结构体类型,但是在OC中是基本数据类型,所以,如果在Swift只是表示一个简单的基本数据类型的话,OC可以转换,如果表示的是一个结构体才有的功能,那么OC无法转换。

class ViewController: UIViewController {

    @objc var a: String?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

}

这里的变量a可以转换,查看一下工程名-Swift.h文件,的确生成了OC头文件:

SWIFT_CLASS("_TtC4TEST14ViewController")
@interface ViewController : UIViewController
@property (nonatomic, copy) NSString * _Nullable a;
- (void)viewDidLoad;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
@end

如果将这里的a类型改为Int会怎么样:

class ViewController: UIViewController {

    @objc var a: Int?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

}

会报错:Property cannot be marked @objc because its type cannot be represented in Objective-C

今天正在导致我发现这个问题的是下面的代码:

typealias TestClouse = (String,Int?) -> ()

class ViewController: UIViewController {

    
    @objc var clouse: TestClouse?
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

}

系统会报上面提到的错误,但是停在clouse变量这行。道理还是一样的。

这里就是上面解释的,当Int成为可选类型的时候,这里的Int已经不光是表示一个简单的Int类型了,而是带有明显的结构体属性,因为是可选,即表示,可能是nil,而OC里的Int类型或者NSInteger都是基本数据类型,不能为nil

所以,要解决这个问题,只能在Swift中避免将OC中的基本数据类型设置为可选类型。

附上系统转换的OC头文件代码:

@interface ViewController : UIViewController
@property (nonatomic, copy) void (^ _Nullable clouse)(NSString * _Nonnull, NSInteger);
- (void)viewDidLoad;
- (nonnull instancetype)initWithNibName:(NSString * _Nullable)nibNameOrNil bundle:(NSBundle * _Nullable)nibBundleOrNil OBJC_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder * _Nonnull)aDecoder OBJC_DESIGNATED_INITIALIZER;
@end

6.OC不支持Swift中的泛型,虽然从Xcode7,OC就引入了泛型的支持,但是这个泛型,我们称作轻量级泛型,和Swift中的重量级泛型还是对不上,当然,硬是要去对接,苹果应该也能做,但毕竟不是同一个东西,强行对接反而不好。
参考Stack Overflow上的讨论

目前遇到这几个问题,后面有新问题再更新

参考资料:swift: @objc的使用

相关文章

  • OC调用Swift framework

    在此记录下OC如何调Swift framework! 新建工程OCCallSwift,语言选择OC,如图:imag...

  • OC调Swift的问题记录

    Swift调OC比较简单,之所以这么说,是因为Swift覆盖OC的大部分功能,即使有些没有覆盖,官方肯定也会给出解...

  • Swift和OC混合开发

    在swift项目上的Swift和OC混合开发 1、Swift调OC方法: (1)、直接新建OC项目会自动创建桥梁文...

  • 20-Swift调用OC和OC调用Swift

    一、Swift调用OC 创建一个Swift语言的工程; 用OC语言创建一个Person类:Swift调OC-1此时...

  • oc swift混编

    1.oc调swift "#import "项目名字-Swift.h" 直接在需要用到swift的oc文件里添加此头...

  • **iOS OC** 转 **Swift**开发问题记录

    iOS OC 转 Swift开发问题记录 之前一直使用OC语言开发iOS应用,时代在进步,使用Swift语言开发已...

  • Swift中关于NSClassFromString获取不到类

    Swift中关于NSClassFromString获取不到类 当Swift中调用OC写的类 直接 当Swift中调...

  • OC转Swift

    记录下OC转Swift的一些经历 文件区别 OC:.h声明 .m实现 Swift:.swift 声明+实现 参数...

  • iOS14 Widget从开发到上线 (六)

    这篇我们说Swift怎么调oc 上一篇我们说过SDemo-Bridging-Header这个桥接文件(Swift调...

  • 截屏并保存到本地

    1>截图 2> 保存图片 3>回调 4>使用Swift注意点:Swift由于是直接将OC转化成Swift语法的,所...

网友评论

      本文标题:OC调Swift的问题记录

      本文链接:https://www.haomeiwen.com/subject/khvezxtx.html