无法从Objective-C访问Swift类型的属性
我正试图从Objective-C访问Swift类的无法从Objective-C访问Swift类型的属性,objective-c,swift,types,objective-c-swift-bridge,Objective C,Swift,Types,Objective C Swift Bridge,我正试图从Objective-C访问Swift类的Double?属性 类BusinessDetailViewController:UIViewController{ var lat:双倍? 瓦隆:双份? //其他元素。。。 } 在另一个视图控制器中,我尝试访问lat,如下所示: #导入“i5km Swift.h” @界面视图控制器() @属性(强,非原子)BusinessDetailViewController*BusinessDetailViewController; @结束 @实现视图控制
Double?
属性
类BusinessDetailViewController:UIViewController{
var lat:双倍?
瓦隆:双份?
//其他元素。。。
}
在另一个视图控制器中,我尝试访问lat
,如下所示:
#导入“i5km Swift.h”
@界面视图控制器()
@属性(强,非原子)BusinessDetailViewController*BusinessDetailViewController;
@结束
@实现视图控制器
-(无效)viewDidLoad
{
[超级视图下载];
self.businessDetailViewController=[[businessDetailViewController alloc]initWithNibName:@“businessDetailViewController”捆绑包:nil];
self.businessDetailViewController.lat=businessArray[1];/*这给了我一个错误*/
}
我越来越
在类型为“BusinessDetailViewController*”的对象上未找到属性“lat”
为什么我不能访问此属性?我缺少什么?非Objective-C类型的可选值没有桥接到Objective-C中。也就是说,Objective-C中可以使用下面
TestClass
的前三个属性,但第四个属性不可用:
class TestClass: NSObject {
var nsNumberVar: NSNumber = 0 // obj-c type, ok
var nsNumberOpt: NSNumber? // optional obj-c type, ok
var doubleVar: Double = 0 // bridged Swift-native type, ok
var doubleOpt: Double? // not bridged, inaccessible
}
在Objective-C代码中,您可以访问前三个属性,如下所示:
TestClass *optTest = [[TestClass alloc] init];
optTest.nsNumberOpt = @1.0;
optTest.nsNumberVar = @2.0;
optTest.doubleVar = 3.0;
在您的情况下,您可以将lat
和long
转换为非可选,或者将它们切换为NSNumber
的实例
请注意,如果您采用第二种方法(将
lat
和lon
切换到类型为NSNumber
的非可选属性),您需要小心使用Objective-C代码,而Swift编译器将阻止您将nil
分配到非可选属性,Objective-C编译器毫不犹豫地允许它,允许nil
值潜入您的Swift代码中,而不可能在运行时捕获它们。在<代码> TestClass < /代码>:< /P>中考虑此方法
extension TestClass {
func badIdea() {
// print the string value if it exists, or 'nil' otherwise
println(nsNumberOpt?.stringValue ?? "nil")
// non-optional: must have a value, right?
println(nsNumberVar.stringValue)
}
}
如果使用这两个属性中的值进行调用,这可以正常工作,但是如果Objective-C代码中的nsNumberVar
设置为nil
,这将在运行时崩溃。请注意,在使用前无法检查nsNumberVar
是否为nil
TestClass *optTest = [[TestClass alloc] init];
optTest.nsNumberOpt = @1.0;
optTest.nsNumberVar = @2.0;
[optTest badIdea];
// prints 1, 2
optTest.nsNumberOpt = nil;
optTest.nsNumberVar = nil;
[optTest badIdea];
// prints nil, then crashes with an EXC_BAD_ACCESS exception
Optionals是swift特有的功能,在obj-c中不可用。可选类实例之所以有效,是因为nil可选可以映射到nil值,但值类型(int、float等)是而不是引用类型,因此这些类型的变量不存储引用,而是存储值本身 我不知道是否有解决方案-一种可能的解决方法是创建非可选属性,将
nil
值映射到未使用的数据类型值(例如,表示索引时为-1,坐标为999999):
这将向obj-c公开\u lat
和\u lon
属性
请注意,我从未尝试过,因此请告诉我们它是否有效。如果您的属性是Swift协议类型,只需在它前面添加
@objc
例如:
class Foo: UIViewController {
var delegate: FooDelegate?
...
}
@objc protocol FooDelegate {
func bar()
}
[UInt?
Int?
或Double?
properties]无法标记为@objc,因为其类型无法在Objective-C中表示
但是,可以将其“包装”为NSN编号,如下所示:
class Foo {
var bar: Double?
}
// MARK: Objective-C Support
extension Foo {
/// bar is `Double?` in Swift and `(NSNumber * _Nullable)` in Objective-C
@objc(bar)
var z_objc_bar: NSNumber? {
get {
return bar as NSNumber?
}
set(value) {
bar = value?.doubleValue ?? nil
}
}
}
我不知道,因为在businessDetailViewController中,我还有一个outlet
@IBOutlet var mapView:MKMapView?
我可以从外部访问它,但它没有公共
我认为可选结构在Objective-C中不可见。将进行验证。我无法在文档中跟踪它,但编译器会告诉您它不能用@objc协议表示{var-lat:Double?{get}
关于这方面的文档是不完整的-例如,说Swift中定义的枚举和结构在Obj-C中不可用,但没有提到Optionals(作为enum
实现)大多数构建的struct
类型在到达之前都会正确桥接。@NateCook我无法证明这一点,但我认为可选的NSNumber
是桥接的,可选的Int
或Float
不是桥接的,因为NSNumber
是一个引用类型,而。None
映射到nil
,而v值类型在objc中没有对应的nil
agree@Antonio:没错-在Objective-C中,任何引用类型都可以是nil
,因此它们会自动桥接到Swift optionals。事实上,有人可能会说,在桥接项目中,任何引用类型都不应该是非可选的,因为您甚至可以将nil
分配给Objective-C中的非可选属性,从而导致无追索权的潜在崩溃。请参阅我的补充内容…很好地了解-不要在objc端使用桥接,但我需要记住的是(发生这种情况只是时间问题:))试试看,是的,我们可以从外面进入,谢谢。
class Foo {
var bar: Double?
}
// MARK: Objective-C Support
extension Foo {
/// bar is `Double?` in Swift and `(NSNumber * _Nullable)` in Objective-C
@objc(bar)
var z_objc_bar: NSNumber? {
get {
return bar as NSNumber?
}
set(value) {
bar = value?.doubleValue ?? nil
}
}
}