objective-c - 如何从 Swift 调用 Objective-C 代码?

标签 objective-c swift

在 Swift 中,如何调用 Objective-C 代码?

Apple 提到它们可以在一个应用程序中共存,但这是否意味着技术上可以重用 Objective-C 中创建的旧类,同时在 Swift 中构建新类?

最佳答案

在 Swift 中使用 Objective-C 类

If you have an existing class that you'd like to use, perform Step 2 and then skip to Step 5. (For some cases, I had to add an explicit #import <Foundation/Foundation.h to an older Objective-C File.)

第 1 步:添加 Objective-C 实现 -- .m

添加.m文件到您的类(class),并将其命名为 CustomObject.m .

第 2 步:添加桥接 header

添加您的 .m 时文件时,您可能会收到如下所示的提示:

A macOS sheet-style dialog from Xcode asking if you would "like to configure an Objective-C bridging header"

点击!

如果您没有看到提示,或者意外删除了桥接 header ,请添加新的 .h文件到您的项目并将其命名为 <#YourProjectName#>-Bridging-Header.h .

在某些情况下,特别是在使用 Objective-C 框架时,您没有显式添加 Objective-C 类,并且 Xcode 无法找到链接器。在本例中,创建您的 .h文件名称如上所述,然后确保在目标的项目设置中链接其路径,如下所示:

An animation demonstrating the above paragraph

注意:

最佳实践是使用 $(SRCROOT) 链接您的项目宏,这样如果您移动您的项目,或者使用远程存储库与其他人一起处理它,它仍然可以工作。 $(SRCROOT)可以被认为是包含 .xcodeproj 文件的目录。它可能看起来像这样:

$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h

第 3 步:添加 Objective-C header -- .h

添加另一个.h文件并将其命名为 CustomObject.h .

第 4 步:构建您的 Objective-C 类

CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

CustomObject.m

#import "CustomObject.h"

@implementation CustomObject 

- (void) someMethod {
    NSLog(@"SomeMethod Ran");
}

@end

第 5 步:将类添加到桥接 header

YourProject-Bridging-Header.h :

#import "CustomObject.h"

第 6 步:使用您的对象

SomeSwiftFile.swift :

var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

无需显式导入;这就是桥接 header 的用途。

在 Objective-C 中使用 Swift 类

第 1 步:创建新的 Swift 类

添加.swift文件添加到您的项目中,并将其命名为 MySwiftObject.swift .

MySwiftObject.swift :

import Foundation

@objc(MySwiftObject)
class MySwiftObject : NSObject {

    @objc
    var someProperty: AnyObject = "Some Initializer Val" as NSString

    init() {}

    @objc
    func someFunction(someArg: Any) -> NSString {
        return "You sent me \(someArg)"
    }
}

第 2 步:将 Swift 文件导入 ObjC 类

SomeRandomClass.m :

#import "<#YourProjectName#>-Swift.h"

文件:<#YourProjectName#>-Swift.h应该已经在您的项目中自动创建,即使您看不到它。

第 3 步:使用您的类

MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);

NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];

NSLog(@"RetString: %@", retString);

注释:

  1. 如果代码完成的行为不符合您的预期,请尝试使用 R 运行快速构建以帮助 Xcode从 Swift 上下文中查找一些 Objective-C 代码,反之亦然。

  2. 如果添加.swift文件到旧项目并收到错误 dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib ,完全尝试restarting Xcode .

  3. 虽然最初可以使用纯 Swift 类(不是 NSObject 的后代),但通过使用 @objc 对 Objective-C 可见。前缀,这不再可能了。现在,要在 Objective-C 中可见,Swift 对象必须是符合 NSObjectProtocol 的类。 (最简单的方法是继承 NSObject ),或者成为 enum标记@objc具有某种整数类型的原始值,如 IntYou may view the edit history for an example of Swift 1.x code using @objc without these restrictions.

关于objective-c - 如何从 Swift 调用 Objective-C 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27099160/

相关文章:

objective-c - NSFileManager 不从 NSFileExtendedAttributes 读取 kMDItemWhereFroms

iphone - iOS:有条件地加载 View Controller

swift - 类型 'OSType' 不符合 Swift 2.0 中的协议(protocol) 'AnyObject'

swift - 我可以覆盖已被扩展覆盖的 Swift 方法吗?

objective-c - 使用 Objective-C 工厂方法在 Swift 中创建对象会出现编译器错误

objective-c - ARC 的内存泄漏

objective-c - 如何将菜单项的按键等效显示设置为多个字符?

objective-c - 当 UIVIew 隐藏在 SameView 中时如何对 UIview 进行动画处理

ios - 以编程方式在垂直堆栈 View 内添加多个水平堆栈 View

ios - iOS 系统默认的希伯来语字体是什么?