IT박스

Objective-C에서 Swift 유형의 속성에 액세스 할 수 없습니다.

itboxs 2020. 12. 4. 08:02
반응형

Objective-C에서 Swift 유형의 속성에 액세스 할 수 없습니다.


Double?Objective-C에서 Swift 클래스의 속성 에 액세스하려고합니다 .

class BusinessDetailViewController: UIViewController {

    var lat : Double?
    var lon : Double?

    // Other elements...
}

다른 뷰 컨트롤러에서 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아래는 것이 목표 - 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;

귀하의 경우에는 latlong비 선택 사항으로 변환 하거나 NSNumber.


두 번째 접근 방식 (전환 latlon유형의 비 선택적 속성 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

If your property is a Swift protocol type, just add @objc in front of it.

Example:

class Foo: UIViewController {
   var delegate: FooDelegate?
   ...
}

@objc protocol FooDelegate {
   func bar()
}

Optionals is a swift specific feature, not available in obj-c. Optional class instances work because a nil optional can be mapped to a nil value, but value types (int, floats, etc.) are not reference types, hence variable of those types don't store a reference, but the value itself.

I don't know if there's a solution - a possible workaround is creating non optional properties mapping the nil value to an unused data type value (such as -1 when representing an index, or 999999 for a coordinate):

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
}

That should expose the _lat and _lon properties to obj-c.

Note that I have never tried that, so please let us know if it works.


[UInt? Int? or Double? properties] cannot be marked @objc because its type cannot be represented in Objective-C.

It is, however, possible to "wrap" them in a NSNumber like so :

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
        }
    }
}

참고URL : https://stackoverflow.com/questions/26366082/cannot-access-property-on-swift-type-from-objective-c

반응형