用Objective-C类别扩展Swift类 [英] Extending a Swift class with Objective-C category

查看:101
本文介绍了用Objective-C类别扩展Swift类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用Objective-C类别来扩展Swift类的情况.我做了如下操作:

在"SomeClass.swift"中:

class SomeClass: NSObject {
}

在"SomeClass + Extension.h"中:

#import "Project-Swift.h"
@interface SomeClass (Extension) 
-(void)someMethod();
@end

效果很好.而且,如果我尝试在我的Objective C代码中使用SomeClass扩展,那就很好了.

问题是,如果我想在另一个Swift类中使用someMethod(),则需要将SomeClass+Extension.h文件放入我的ObjC-BridgingHeader.h文件中.

但是这样做会导致循环依赖,因为SomeClass+Extension.h也会导入Project-Swift.h.

有人能解决这个问题吗?

请注意,仅在类别标头中向前声明该类是行不通的,因为类别本身无法使用正向声明:

@class SomeClass而不导入Project-Swift.h会给出编译错误.

解决方案

糟糕的

我也一直在与这个问题作斗争.不幸的是,

如果需要支持两个以上的输入参数,或者需要更紧密的类型耦合,我建议您使用运行时来调用基础函数. 此处.. >

Im in a situation where I need to use Objective-C category to extend a Swift class. I've done something as follows:

In "SomeClass.swift":

class SomeClass: NSObject {
}

In "SomeClass+Extension.h":

#import "Project-Swift.h"
@interface SomeClass (Extension) 
-(void)someMethod();
@end

This has worked well. And if I try to use the SomeClass extension in my Objective C code, it is fine.

The problem is, if I want to use someMethod() in a another Swift class, I will need to put the SomeClass+Extension.h file into my ObjC-BridgingHeader.h file.

But doing this will cause a circular dependency, because SomeClass+Extension.h also imports Project-Swift.h.

Does anyone have a good way to get around this?

Please note that simply forward declaring the class in the category header will not work, as categories cannot use forward declarations for it's own implementation as so:

@class SomeClass without importing Project-Swift.h will give a compile error.

解决方案

The Bad

i too have been fighting this issue a bunch. unfortunately the documentation pretty explicitly states that this pattern is not allowed:

To avoid cyclical references, don’t import Swift code into an Objective-C header (.h) file. Instead, you can forward declare a Swift class or protocol to reference it in an Objective-C interface.

Forward declarations of Swift classes and protocols can only be used as types for method and property declarations.

also throughout the the linked page you will notice it keeps mentioning to import the generated header specifically into the .m file:

To import Swift code into Objective-C from the same target

Import the Swift code from that target into any Objective-C .m file within that target

The Good

one solution that may work for you is to create a swift extension that redefines each method you need in the category. it is fragile and ugly, but arguably the cleanest solution.

/**
 Add category methods from objc here (since circular references prohibit the ObjC extension file)
 */
extension SomeClass {
    @nonobjc func someMethod() {
        self.performSelector(Selector("someMethod"))
    }
}

  • adding the @noobjc to the front allows the same method signature to be used w/o overriding the ObjC implementation
  • now the import "SomeClass+Extension.h" from the bridging header can be removed

if support for more than two input params is needed, or tighter type coupling is desired i would recommend using the runtime to call the underlying function. a great description is here.

这篇关于用Objective-C类别扩展Swift类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆