无法从Objective-C访问Swift类型的属性 [英] Cannot access property on Swift type from Objective-C

查看:86
本文介绍了无法从Objective-C访问Swift类型的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从Objective-C访问Swift类的Double?属性.

I am trying to access a Swift class's Double? property from Objective-C.

class BusinessDetailViewController: UIViewController {

    var lat : Double?
    var lon : Double?

    // Other elements...
}

在另一个视图控制器中,我正在尝试访问lat,如下所示:

In another view controller, I am trying to access lat like following:

#import "i5km-Swift.h"
@interface ViewController ()

@property (strong, nonatomic) BusinessDetailViewController *businessDetailViewController;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.businessDetailViewController = [[BusinessDetailViewController alloc] initWithNibName:@"BusinessDetailViewController" bundle:nil];
    self.businessDetailViewController.lat = businessArray[1]; /* THIS GIVES ME AN ERROR */
}

我得到了

在类型'BusinessDetailViewController *'的对象上找不到属性'lat'

Property 'lat' not found on object of type 'BusinessDetailViewController *'

为什么我不能访问此属性?我想念什么?

Why can't I access this property? What am I missing?

推荐答案

非Objective-C类型的可选值不会桥接到Objective-C中.也就是说,下面的TestClass的前三个属性将在Objective-C中可用,但第四个属性则不会:

Optional values of non-Objective-C types aren't bridged into Objective-C. That is, the first three properties of TestClass below would be available in Objective-C, but the fourth wouldn't:

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代码中,您将像这样访问前三个属性:

In your Objective-C code, you'd access those first three properties like this:

TestClass *optTest = [[TestClass alloc] init];
optTest.nsNumberOpt = @1.0;
optTest.nsNumberVar = @2.0;
optTest.doubleVar = 3.0;

根据您的情况,您可以将latlong转换为非可选,也可以将它们切换为NSNumber的实例.

In your case, you can either convert lat and long to be non-Optional or switch them to be instances of NSNumber.

请注意,如果您采用第二种方法(将latlon切换为类型为NSNumber的非可选属性),则需要谨慎对待Objective-C代码-而Swift编译器会阻止您从将nil分配给非可选属性后,Objective-C编译器对允许它毫无限制,让nil值潜入您的Swift代码中,而没有机会在运行时捕获它们.考虑在TestClass上使用此方法:

Note that you need to be careful about your Objective-C code if you take the second approach (switching lat and lon to non-optional properties of type NSNumber) -- while the Swift compiler will prevent you from assigning nil to non-optional properties, the Objective-C compiler has no qualms about allowing it, letting nil values sneak into your Swift code with no chance of catching them at runtime. Consider this method on TestClass:

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

This works fine if invoked with values in both of the properties, but if nsNumberVar is set to nil from the Objective-C code, this will crash at runtime. Note that there is no way to check whether or not nsNumberVar is nil before using it!

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

这篇关于无法从Objective-C访问Swift类型的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆