2017-12-10 8 views
2

Swift 3에서 클래스를 만들어 Cordova 플러그인을 구현하려고합니다. 이 건물은 있지만 실행 중이지만 클래스의 속성에 액세스 할 때마다 응용 프로그램이 충돌합니다. 널처럼 보이는 주소,Objective C 코드로 생성 할 때 Swift 클래스 속성이 초기화되지 않았습니다.

@objc(DSFMediaCentre) 
class DSFMediaCentre : CDVPlugin 
{ 
    var players = [UUID:DSFPlayerHandler](); 
    ... 
} 

및 그러나

@objc(DSFMediaCentre) 
class DSFMediaCentre : CDVPlugin 
{ 
    var players :[UUID:DSFPlayerHandler]; 
    override init() { 
     players = [:]; 
    } 
    ... 
} 

, 내 players 속성을 사용하는 경우, 결과가 EXC_BAD_ACCESS 예외입니다 : 나는 클래스를 초기화하는 두 가지 방법을 시도했습니다 포인터 역 참조.

객체는 내가 전혀 아무 익숙하지 않은 언어입니다 목표 C 코드에 의해 만들지 만, 나는이 그것을 만들어 줄 생각되고있다 :

obj = [[NSClassFromString(className)alloc] initWithWebViewEngine:_webViewEngine]; 

CDVPlugin 클래스는 주석을 포함 initWithWebViewEngine이 오버라이드되어서는 안된다는 것을 알았습니다. (실제로는 CDVPlugin.m 파일에 선언되어있는 동안 CDVPlugin.h에 언급되어 있지 않으므로 Swift 컴파일러가이 메서드를 재정의 할 수 없습니다. 그것을 알기 위해), 오히려 초기화 코드는이라는 메소드에 위치해야합니다대신. 그러나, 그렇게하면 컴파일러 오류가 발생합니다 ("클래스 DSFMediaCentre에 초기화 프로그램이 없습니다").

또한, 나는 다시 내 init() 방법을 넣어 같이, pluginInitialize() 전화를 설정 한 경우 :

오류가 다음 속성 'self.players' "로 변경

이는 super.init 전화에서 초기화되지

override init() { 
    super.init(); // necessary otherwise next line is an error 
    pluginInitialize(); 
} 
override func pluginInitialize() { 
    players = [:]; 
} 
".

이 클래스를 올바르게 초기화하려면 어떻게해야합니까?

+0

아마 당신이 사용하고있는 스위프트 (4)를 초기화 선수를 초기화하지만 여전히 항상 비 nulable 확인 플레이어를 할 필요가 없습니다 게으른 키워드를

lazy var players :[UUID:DSFPlayerHandler] = [:] 

을 사용하는 것입니다 Objective-C에서 @objc로 액세스하는 클래스 + ivars의 접두어가 필요합니까? – Rog

+0

아니요, 저는 신속하게 3을 사용하고 있습니다. 질문에 추가 할 것입니다. 아직 빠른 4를 보지 못했다. – Jules

답변

1

언어에서 요구하는 엄격한 초기화 시스템과 작업중인 프레임 워크에서 사용하는 프로 시저간에 불일치가 있습니다.

스위프트는 a) 객체 구성의 일부로 속성을 초기화해야하며, b) 그 구조가 해당 유형의 상위 유형에 연결되어야 함을 요구합니다. 그러나 CDVPlugin 유형이 사용자를 대신하여 작업을 수행하고 있습니다. 당신은 그것을 사용자 정의 할 수있는 능력이 없습니다. (이는 Swift와 같은 컴파일 시간 제한이 없기 때문에 ObjC에서 더 합리적입니다.)

상황은 nib 파일에서 개체의 압축을 푸는 것과 비슷합니다. 이 경우에도 객체를 생성하는 펜촉 로딩 시스템이므로 이니셜 라이저를 사용자 정의 할 수 없습니다. 유형은 항상 init(coder:)으로 생성됩니다. 특정 의미에서 초기화 지점은 awakeFromNib() 등으로 더 아래로 이동합니다. 그 중에서도 아카이브의 다른 객체에 대한 콘센트는 선택 사항으로 선언되고 일반적으로 암시 적으로 언 래핑됩니다.

같은 해결책을 사용하십시오. pluginInitialize()을 초기화 지점으로 간주해야합니다. 그런 다음 언어는 초기화 지점에서 채워지지 않으므로 속성을 선택적으로 지정해야합니다. 그러므로 재산을 IUO로 만드십시오 :

@objc(DSFMediaCentre) 
class DSFMediaCentre : CDVPlugin 
{ 
    var players :[UUID:DSFPlayerHandler]! 
    override func pluginInitialize() { 
     players = [:]; 
    } 
} 

모두가 좋아야합니다.

1

다른 솔루션은 그래서, 당신은