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
}
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;
In your case, you can either convert lat
and long
to be non-Optional or switch them to be instances of NSNumber
.
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)
}
}
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
@IBOutlet var mapView: MKMapView?
and I can access it from outside but it does not havepublic
– tranvutuan