在objective-C中不可见的swift init

时间:2022-09-07 11:20:30

I'm trying to create init functions in Swift and create instances from Objective-C. The problem is that I don't see it in Project-Swift.h file and I'm not able to find the function while initializing. I have a function defined as below:

我尝试用Swift创建init函数,并从Objective-C创建实例。问题是我没有在Project-Swift中看到它。h文件,初始化时找不到函数。我有一个函数定义如下:

public init(userId: Int!) {
    self.init(style: UITableViewStyle.Plain)
    self.userId = userId
}

I even tried putting @objc(initWithUserId:) and I keep getting the same error again. Is there anything else I'm missing? How do I get the constructor visible to Objective-C code?

我甚至尝试过输入@objc(initWithUserId:),然后我又得到了同样的错误。我还缺什么吗?如何使构造函数对Objective-C代码可见?

I read the below for this:

我读了下面的内容:

https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/Initialization.html

https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/Initialization.html

https://developer.apple.com/library/ios/documentation/swift/conceptual/buildingcocoaapps/interactingwithobjective-capis.html

https://developer.apple.com/library/ios/documentation/swift/conceptual/buildingcocoaapps/interactingwithobjective-capis.html

How to write Init method in Swift

如何快速编写Init方法?

How to define optional methods in Swift protocol?

如何在Swift协议中定义可选方法?

1 个解决方案

#1


27  

The issue you're seeing is that Swift can't bridge optional value types -- Int is a value type, so Int! can't be bridged. Optional reference types (i.e., any class) bridge correctly, since they can always be nil in Objective-C. Your two options are to make the parameter non-optional, in which case it would be bridged to ObjC as an int or NSInteger:

您看到的问题是Swift不能桥接可选值类型——Int是一个值类型,所以Int!无法弥合。可选的引用类型(即。,任何类)桥接正确,因为在Objective-C中它们总是为nil。您的两个选项是使参数为非可选的,在这种情况下,它将被作为int或NSInteger桥接到ObjC:

// Swift
public init(userId: Int) {
    self.init(style: UITableViewStyle.Plain)
    self.userId = userId
}

// ObjC
MyClass *instance = [[MyClass alloc] initWithUserId: 10];

Or use an optional NSNumber!, since that can be bridged as an optional:

或者使用一个可选的NSNumber!,因为这可以作为一个可选的:

// Swift
public init(userId: NSNumber!) {
    self.init(style: UITableViewStyle.Plain)
    self.userId = userId?.integerValue
}

// ObjC
MyClass *instance = [[MyClass alloc] initWithUserId: @10];    // note the @-literal

Note, however, you're not actually treating the parameter like an optional - unless self.userId is also an optional you're setting yourself up for potential runtime crashes this way.

但是,请注意,您实际上并没有把参数当作可选的——除非是self。userId也是一个可选的选项,您可以通过这种方式为自己设置可能的运行时崩溃。

#1


27  

The issue you're seeing is that Swift can't bridge optional value types -- Int is a value type, so Int! can't be bridged. Optional reference types (i.e., any class) bridge correctly, since they can always be nil in Objective-C. Your two options are to make the parameter non-optional, in which case it would be bridged to ObjC as an int or NSInteger:

您看到的问题是Swift不能桥接可选值类型——Int是一个值类型,所以Int!无法弥合。可选的引用类型(即。,任何类)桥接正确,因为在Objective-C中它们总是为nil。您的两个选项是使参数为非可选的,在这种情况下,它将被作为int或NSInteger桥接到ObjC:

// Swift
public init(userId: Int) {
    self.init(style: UITableViewStyle.Plain)
    self.userId = userId
}

// ObjC
MyClass *instance = [[MyClass alloc] initWithUserId: 10];

Or use an optional NSNumber!, since that can be bridged as an optional:

或者使用一个可选的NSNumber!,因为这可以作为一个可选的:

// Swift
public init(userId: NSNumber!) {
    self.init(style: UITableViewStyle.Plain)
    self.userId = userId?.integerValue
}

// ObjC
MyClass *instance = [[MyClass alloc] initWithUserId: @10];    // note the @-literal

Note, however, you're not actually treating the parameter like an optional - unless self.userId is also an optional you're setting yourself up for potential runtime crashes this way.

但是,请注意,您实际上并没有把参数当作可选的——除非是self。userId也是一个可选的选项,您可以通过这种方式为自己设置可能的运行时崩溃。