OC调Swift的问题记录

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的使用

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 5,890评论 0 9
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,744评论 4 61
  • 暮雪入画别离上心头 借酒消愁愁亦不肯休 折尽了柳诉不尽离愁 满是红豆映你的双眸
    芊雨落阅读 461评论 0 1
  • 昨晚喝tequila醉倒在家里之后,就下定决心要说一说它。 昨天晚上特别开心,因为就要辞职跟之前的生活说拜拜了,然...
    清热解毒陳槑槑阅读 3,025评论 0 1
  • 第05期目标达成术分别从方向与路径、目标与任务、计划与能量三个方面进行了课程的展开,还有实践(结果以表格填写形式展...
    快鱼up阅读 1,423评论 0 1

友情链接更多精彩内容