无法从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; @结束 @实现视图控制

我正试图从Objective-C访问Swift类的
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
        }
    }
}