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

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

推荐答案

Using Objective-C Classes in Swift

如果您想使用现有的类,请执行Step 2,然后跳到Step 5.(在某些情况下,我必须在旧的Objective-C文件中添加显式#import <Foundation/Foundation.h.)

第一步:添加Objective-C实现--.M

向类中添加一个.m文件,并将其命名为CustomObject.m.

第2步:添加桥接头

添加.m文件时,可能会出现如下提示:

A macOS sheet-style dialog from Xcode asking if you would

点击Yes

如果没有看到提示,或者不小心删除了桥接头,请向项目中添加一个新的.h文件,并将其命名为<#YourProjectName#>-Bridging-Header.h.

在某些情况下,尤其是在使用Objective-C框架时,没有显式添加Objective-C类,Xcode找不到链接器.在这种情况下,创建名为上述名称的.h文件,然后确保在目标的项目设置中链接其路径,如下所示:

演示上述段落的动画

Note:

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

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

第3步:添加Objective-C标题--.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:将类添加到桥接头

YourProject-Bridging-Header.h年:

#import "CustomObject.h"

步骤6:使用您的对象

SomeSwiftFile.swift年:

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

无需明确导入;这就是桥接头的作用.

Using Swift Classes in Objective-C

第一步:创建新的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应该已经在您的项目中自动创建,即使您看不到它.

第三步:利用你的课堂

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. 如果代码完成没有达到预期效果,请try 使用R帮助Xcode从Swift上下文中找到一些Objective-C代码,反之亦然.

  2. 如果将.swift文件添加到较旧的项目中,并出现错误dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib,请try 完全restarting Xcode.

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

Swift相关问答推荐

数据不会被ARC删除在swift'

如何在Swift中获得与Python相同的HMAC—SHA512签名?

使用SWIFT宏从另一个枚举添加 case

SWIFT Vapor控制台应用程序-操作无法完成.权限被拒绝

RxSwift .debounce,.throttle用于分页

查找数组中 ** 元素 ** 的属性的最小值和最大值

我可以为UIMenu设定一个固定的订单吗?

不能将符合协议的SWIFT类的实例分配给需要该协议的Objective-C属性

从SwiftUI使用UIPageView时,同一页面连续显示两次的问题

如何避免切换视图递归onChange调用SwiftUI

有条件地在同一视图上设置两个不同的过渡

如何增加 NSStatusBar 图像大小?

快速更改tableView中的数据

自定义 DispatchQueue 服务质量

供应和普通数组中具有空值的 map 函数的行为不一致?

类型 '()' 不能符合 View (除非它肯定是 View,这次没有恶作剧)

ZStack 中的 ProgressView 与 View 的行为不同

如何在 Swift 中复制字典?

无法推断泛型参数的参数

快速覆盖属性