无法从Objective-C访问Swifttypes的属性
我正在试图从客观的C类调用一个快速的var。 我在做什么如下:
Swift类
class BusinessDetailViewController: UIViewController { var lat : Double? var lon : Double? @IBOutlet var mapView: MKMapView? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) // Here you can init your properties } required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
在ViewController.m中,我试图像下面这样调用lat
:
#import "i5km-Swift.h" @interface ViewController () @property (strong, nonatomic) BusinessDetailViewController *businessDetailViewController; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. self.businessDetailViewController = [[BusinessDetailViewController alloc] initWithNibName:@"BusinessDetailViewController" bundle:nil]; self.businessDetailViewController.lat = businessArray[1]; /* THIS GIVES ME AN ERROR */ }
我越来越
Property 'lat' not found on object of type 'BusinessDetailViewController *'
任何想法为什么我不能访问或我缺less别的东西。
非Objective-Ctypes的可选值不会桥接到Objective-C中。 也就是说,下面的TestClass
的前三个属性将在Objective-C中可用,但是第四个属性不会:
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
types的非可选属性),则需要注意Objective-C代码 – 而Swift编译器会阻止将nil
分配给非可选属性,Objective-C编译器毫无疑问地允许它,让nil
值潜入你的Swift代码中,而不会在运行时捕获它们。 考虑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) } }
如果在这两个属性中都使用值来调用,这可以正常工作,但如果nsNumberVar
从Objective-C代码设置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
如果你的属性是一个Swift协议types,只需在它前面添加@objc
。
例:
class Foo: UIViewController { var delegate: FooDelegate? ... } @objc protocol FooDelegate { func bar() }
Optionals是一个快捷的特定function,在obj-c中不可用。 可选的类实例工作,因为一个可选的nil可以映射到一个零值,但值types(int,浮点数等) 不是引用types,因此这些types的variables不存储引用,但值本身。
我不知道是否有解决scheme – 一个可能的解决方法是创build非零值的可选属性映射到一个未使用的数据types的值(例如-1代表一个索引,或999999的坐标):
class Test { var lat : Double? { didSet { self._lat = self.lat != nil ? self.lat! : 999999 } } var lon : Double? { didSet { self._lon = self.lon != nil ? self.lon! : 999999 } } var _lat: Double = 99999999 var _lon: Double = 99999999 }
这应该将_lat
和_lon
属性暴露给obj-c。
请注意,我从来没有尝试过,所以请让我们知道,如果它的作品。
迅速:
static func foo1() { print ("foo1") } static func foo2(p1 : Int) { print ("foo2 \(p1)") }
可以从ObjectiveC中调用:
[className foo1]; [className foo2:123];
之前我有一个IF语句的错误情况(!):
if(Fingerprint.foo1) { // NOT A CALL TO METHOD!
这个编译好吧。 但是这个语句不会调用foo1方法,它会检查属性(!)是否存在(返回YES / NO)。 这确实让我有些失落。