SwiftクラスのDouble?
Objective-Cのプロパティ。
class BusinessDetailViewController: UIViewController {
var lat : Double?
var lon : Double?
// Other elements...
}
別のView Controllerで、次のようにlat
にアクセスしようとしています:
#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」が見つかりません
このプロパティにアクセスできないのはなぜですか?私は何が欠けていますか?
非Objective-C型のオプション値はObjective-Cにブリッジされません。つまり、以下のTestClass
の最初の3つのプロパティwouldはObjective-Cで使用できますが、4番目は使用できません。
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コードでは、次のような最初の3つのプロパティにアクセスします。
TestClass *optTest = [[TestClass alloc] init];
optTest.nsNumberOpt = @1.0;
optTest.nsNumberVar = @2.0;
optTest.doubleVar = 3.0;
あなたの場合、lat
とlong
を非オプションに変換するか、NSNumber
のインスタンスに切り替えることができます。
2番目のアプローチ(lat
およびlon
をNSNumber
型のオプションではないプロパティに切り替える)を行う場合、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)
}
}
両方のプロパティの値で呼び出された場合、これは正常に機能しますが、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
プロパティがSwiftプロトコルタイプの場合、@objc
その前。
例:
class Foo: UIViewController {
var delegate: FooDelegate?
...
}
@objc protocol FooDelegate {
func bar()
}
オプションはSwift特定の機能、obj-cでは使用不可。オプションのクラスインスタンスは、nilオプションをnil値にマップできるが、値の型(int、floatなど) not参照型であるため、これらの型の変数は参照を格納せず、値自体を格納します。
解決策があるかどうかはわかりません-可能な回避策は、nil
値を未使用のデータ型値にマッピングするオプションでないプロパティを作成することです(インデックスを表す場合は-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に公開されます。
私はこれを試したことがないので、うまくいくかどうかをお知らせください。
[
UInt?
Int?
またはDouble?
プロパティ]は、Objective-Cで型を表すことができないため、@ objcとしてマークできません。
ただし、次のようにNSNumberで「ラップ」することは可能です。
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
}
}
}