programing

클래스는 슈퍼클래스의 필수 멤버를 구현하지 않습니다.

sourcejob 2023. 4. 24. 23:10
반응형

클래스는 슈퍼클래스의 필수 멤버를 구현하지 않습니다.

그래서 오늘 Xcode 6 베타 5로 업데이트했는데, Apple의 수업의 거의 모든 하위 클래스에서 오류가 발생하였습니다.

에러 상태는 다음과 같습니다.

클래스 'x'는 슈퍼클래스의 필수 멤버를 구현하지 않습니다.

이 클래스는 현재 매우 가볍기 때문에 게시하기 쉽기 때문에 제가 선택한 한 가지 예가 있습니다.

class InfoBar: SKSpriteNode  { //Error message here

    let team: Team
    let healthBar: SKSpriteNode

    init(team: Team, size: CGSize) {
        self.team = team
        if self.team == Team.TeamGood {
            healthBar = SKSpriteNode(color: UIColor.greenColor(), size:size)
        }
        else {
            healthBar = SKSpriteNode(color: UIColor.redColor(), size:size)
        }
        super.init(texture:nil, color: UIColor.darkGrayColor(), size: size)

        self.addChild(healthBar)

    }

}

이 에러는 왜 발생하고 있으며, 어떻게 하면 해결할 수 있을까요?내가 구현하지 않는 것은 무엇입니까?지정된 이니셜라이저를 호출합니다.

개발자 포럼의 Apple 직원으로부터:

컴파일러 및 빌드된 프로그램에 NSCoding 호환성을 정말로 원하지 않는다고 선언하는 방법은 다음과 같습니다.

required init(coder: NSCoder) {
  fatalError("NSCoding not supported")
}

NSCoding을 준수하고 싶지 않은 경우 이 옵션을 선택할 수 있습니다.스토리보드에서 로드하지 않기 때문에 많은 스프라이트킷 코드를 사용하여 이 방법을 사용해 왔습니다.


이 방법을 사용할 수 있는 다른 방법은 다음과 같이 편리한 초기 설정으로 구현하는 것입니다.

convenience required init(coder: NSCoder) {
    self.init(stringParam: "", intParam: 5)
}

은 「」로 적어 .self이렇게 하면 치명적인 오류가 발생하는 것을 방지하면서 모든 비옵션 속성이 아닌 파라미터에 더미 값만 사용할 수 있습니다.


물론 세 번째 옵션은 super를 호출하면서 메서드를 구현하고 모든 비옵션 속성을 초기화하는 것입니다.오브젝트가 스토리보드에서 로드되는 뷰인 경우 다음 방법을 사용해야 합니다.

required init(coder aDecoder: NSCoder!) {
    foo = "some string"
    bar = 9001

    super.init(coder: aDecoder)
}

Swift 특유의 매우 중요한 정보 중 두 가지가 기존 답변에서 누락되어 있어 이를 완전히 해소하는 데 도움이 된다고 생각합니다.

  1. 되어 있는 , 그의 「Swift」, 「Swift」를 .required키워드를 지정합니다.
  2. 스위프트는 다음과 같은 특별한 상속 규칙을 가지고 있다.init★★★★★★★★★★★★★★★★★★.

tl;dr은 다음과 같습니다.

이니셜라이저를 구현하면 슈퍼클래스의 지정된 이니셜라이저를 더 이상 상속하지 않습니다.

상속되는 이니셜라이저는 슈퍼클래스 편의 이니셜라이저뿐입니다.이 이니셜라이저는 덮어쓰게 된 지정된 이니셜라이저를 가리킵니다.

그럼... 긴 버전에 대한 준비는 됐나?


스위프트는 다음과 같은 특별한 상속 규칙을 가지고 있다.init★★★★★★★★★★★★★★★★★★.

가 만든 두 중 두 인 건 첫 포인트는 수 또 왜 이 포인트인지도 이해할 수 없습니다.required키워드는 이 점을 이해할 때까지 존재합니다.일단 이 점을 이해하면, 다른 하나는 꽤 명백해집니다.

이 답변의 이 섹션에서 다루는 모든 정보는 여기에서 찾을 수 있는 Apple 문서에서 나온 것입니다.

Apple 문서:

Objective-C의 서브클래스와 달리 Swift 서브클래스는 기본적으로 슈퍼클래스 이니셜라이저를 상속하지 않습니다.Swift의 접근방식은 슈퍼클래스의 단순한 이니셜라이저가 보다 전문적인 서브클래스에 상속되는 상황을 방지하고 완전히 또는 올바르게 초기화되지 않은 서브클래스의 새 인스턴스를 만드는 데 사용됩니다.

강조해 주세요.

에서는 Swift 「」, 「Apple」, 「Swift」, 「」, 「Swift」, 「Swift」, 「Swift」, 「Swift」, 「Swift」, 「Swift」, 「Swift」, 「Swift」, 「Swift」, 「Swift」, 「Swift」를 항상 계승하는 은 아닙니다.init★★★★★★★★★★★★★★★★★★.

그럼, 그들은 언제 그들의 슈퍼클래스를 물려받을까요?

가 언제 상속되는지 은 두 .init메서드를 지정합니다.Apple 서: :

규칙 1

하위 클래스에서 지정된 이니셜라이저를 정의하지 않은 경우 모든 슈퍼 클래스 지정된 이니셜라이저를 자동으로 상속합니다.

규칙 2

서브클래스가 모든 슈퍼클래스 지정 이니셜라이저를 구현(규칙 1에 따라 상속하거나 정의의 일부로 커스텀 구현을 제공함으로써)하는 경우 모든 슈퍼클래스 편의 이니셜라이저를 자동으로 상속합니다.

는 이 SKSpriteNode의 »init(coder: NSCoder)을 사용하다

당신의 래,, 신 so는InfoBar는 래스 the the the theitingitingitingitingitingitingitingitingiting 를 .required는 사용자가 한 까지 계속됩니다.init(team: Team, size: CGSize).

init 방법을 해서 당신의 방법을 .InfoBar그러면 사용자는 아직 상속을 받고 있습니다.SKSpriteNode의 »init(coder: NSCoder)그러나 커스텀 이니셜라이저를 추가했을 때 슈퍼클래스의 지정된 이니셜라이저(및 구현한 이니셜라이저를 가리키지 않는 편리한 이니셜라이저)의 상속이 중지되었습니다.

그래서 간단한 예로서 다음과 같이 설명하겠습니다.

class Foo {
    var foo: String
    init(foo: String) {
        self.foo = foo
    }
}

class Bar: Foo {
    var bar: String
    init(foo: String, bar: String) {
        self.bar = bar
        super.init(foo: foo)
    }
}


let x = Bar(foo: "Foo")

그러면 다음 오류가 발생합니다.

호출에 매개 변수 'bar'에 대한 인수가 없습니다.

여기에 이미지 설명 입력

객관적-C의 약칭이다.BarinitWithFoo:브브cc-C에 self.bar재산은 단순할 것이다.nil좋은 상태는 아닐지도 모르지만, 오브젝트가 있는 것은 지극히 유효한 상태입니다.스위프트 오브젝트가 완전히 유효한 상태가 아닙니다. self.bar.nil.

이니셜라이저를 상속하는 유일한 방법은 자신의 이니셜라이저를 제공하지 않는 것입니다. "Delete"를 삭제하여 Bar의 »init(foo: String, bar: String)

class Bar: Foo {
    var bar: String
}

이렇게 슈퍼클래스를 상속하지 됩니다.init★★★★★★★★★★★★★★★★★★:

문제: 클래스 'Bar'에 이니셜라이저가 없습니다.

수정: 이니셜라이저가 없는 저장된 속성 '막대'로 인해 합성 이니셜라이저가 차단됨

저장된 속성을 서브클래스에 추가한 경우 Swift가 해당 서브클래스의 저장된 속성을 알 수 없는 슈퍼클래스 이니셜라이저를 사용하여 해당 서브클래스의 유효한 인스턴스를 만들 수 없습니다.


왜가 아아, 럼 okay okay okay okay okay okay okay를 구현해야 요?init(coder: NSCoder)? ???required

의 ★★★★★★★★★★★★★★★★」init메서드는 특수한 상속 규칙 집합에 의해 재생될 수 있지만 프로토콜 준수는 여전히 체인을 통해 상속됩니다.상위 클래스가 프로토콜을 준수하는 경우 하위 클래스는 해당 프로토콜을 준수해야 합니다.

일반적으로 이것은 문제가 되지 않습니다. 왜냐하면 대부분의 프로토콜은 Swift의 특별한 상속 규칙에 의해 재생되지 않는 메서드만 요구하기 때문입니다. 따라서 프로토콜에 부합하는 클래스에서 상속하는 경우에는 클래스가 프로토콜 준수를 충족할 수 있는 모든 메서드 또는 속성도 상속됩니다.

,의 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.init메서드는 특별한 규칙 집합에 따라 작동하며 항상 상속되는 것은 아닙니다.에, 한 「스페셜」, 「스페셜」을 .init: 「」:NSCoding.init「」라고 하는 )required.

다음 예를 생각해 보겠습니다.

protocol InitProtocol {
    init(foo: Int)
}

class ConformingClass: InitProtocol {
    var foo: Int
    init(foo: Int) {
        self.foo = foo
    }
}

이건 컴파일 되지 않아요.다음 경고가 생성됩니다.

문제: 이니셜라이저 요구 사항 'init(foo:)'은(는) 비최종 클래스 'Conforming Class'의 '필수' 이니셜라이저에서만 충족할 수 있습니다.

수정: 삽입이 필요합니다.

init(foo: Int)이니셜라이저가 필요합니다. 수 .final(어느 쪽이든)

그럼, 내가 하위 클래스로 가면 어떻게 되는거야?이 시점부터, 만약 내가 하위 클래스로 간다면, 난 괜찮아.init(foo:)이제 더 이 말을 때문에 왜냐하면 저는 이제 더 이상 이 명령어를 따르지 않기 때문입니다.InitProtocol를 할더 이상 했다. 프로토콜을 준수하는 클래스에서 서브클래스를 할 수 없다가 갑자기 해당 프로토콜을 더 이상 준수하지 않기로 결정했다.난 프로토콜 준수를 물려받았지만 스위프트가 일하는 방식 때문에init메서드 상속, 해당 프로토콜을 준수하는 데 필요한 부분을 상속받지 못했으며 반드시 구현해야 합니다.


좋아, 이 모든 게 말이 돼.그런데 왜 더 유용한 오류 메시지가 표시되지 않는 거죠?

가, 된 「」, 「」, 「」, 「」, 「」, 「」, 「」에 적합하지 는, 에러 되는 경우가 NSCoding , 해야 합니다.init(coder: NSCoder)★★★★★★★★★★★★★★★★★★.

Xcode를 사용하다왜냐하면 실제로 필요한 메서드를 구현하거나 상속하지 않는 것이 항상 문제가 되는 것은 아니기 때문입니다.init '''」required프로토콜 준수 말고도 그건 공장 방법이야

출하시의 올바른 방법을 타입을 「반환 타입」으로 .SelfSwift objectiveObjective-C)와)instanceType하려면 , 를가 있습니다 하지만 이걸 하기 위해서는required methodinitializer " "

class Box {
    var size: CGSize
    init(size: CGSize) {
        self.size = size
    }

    class func factory() -> Self {
        return self.init(size: CGSizeZero)
    }
}

이로 인해 다음 오류가 발생합니다.

메타 유형 값을 사용하여 클래스 유형 'Self' 개체를 구성하려면 '필수' 이니셜라이저를 사용해야 합니다.

여기에 이미지 설명 입력

이치노Box 우리의 메서드인 클래스 메서드를 합니다.factory 전화도 할 수 SubclassedBox.factory() <고객명>이 없으면 <고객명>이 없습니다requiredinit(size:) 법,,Box가 반드시 self.init(size:) 그그factory을 사용하다

그 합니다.required, 에서 이런하면 ' 반에서 이런 방법을 시행하면' '우리 반에서 '공장이 되다', '공장이 되다', '공장이 되다', '공장이 되다', '공장이 되다', '이 되다', '공장이 되다', '공장이 되다'required와 같은 하게 됩니다.NSCoding프로토콜입니다.


결국 Swift의 이니셜라이저는 상속규칙이 약간 다르므로 슈퍼클래스에서 이니셜라이저를 상속받을 수 없다는 기본적인 이해로 요약됩니다.이 문제는 슈퍼클래스 이니셜라이저가 저장된 새 속성을 알 수 없고 개체를 유효한 상태로 인스턴스화할 수 없기 때문에 발생합니다.가지 를 ,, 러, 러, 여, 음 등으로 표시할 수 .required 실제로 중 할 수 required그렇지 않으면 우리가 직접 구현해야 합니다.

여기서의 요점은, 여기서 나타내는 에러가 발생하고 있는 경우는, 실제로는 클래스가 이 메서드를 실장하고 있지 않은 것을 의미합니다.

Swift Swift 서브클래스를 것은 하겠습니다.init( 이해하는 데 하다고 생각되는) (이 문제를 완전히 하는 데 매우 중요하다고 되는) 예를 .

class Foo {
    init(a: Int, b: Int, c: Int) {
        // do nothing
    }
}

class Bar: Foo {
    init(string: String) {
        super.init(a: 0, b: 1, c: 2)
        // do more nothing
    }
}

let f = Foo(a: 0, b: 1, c: 2)
let b = Bar(a: 0, b: 1, c: 2)

컴파일에 실패한다.

여기에 이미지 설명 입력

에러 메세지가 표시되는 것은, 조금 오해의 소지가 있습니다.

호출에 추가 인수 'b'가 있습니다.

지만요 but but but but but but but but.BarFoo의 »init 두 중 init메서드를 지정합니다.

그 Objective-C를할 것이다.initObjective-C는 오브젝트의 속성을 초기화하지 않고 완벽하게 만족하기 때문에 문제 없습니다(개발자로서 만족하지 말았어야 했습니다).스위프트에서는, 이것은 간단히 할 수 없습니다.잘못된 상태를 가질 수 없으며 슈퍼클래스 이니셜라이저를 상속하면 개체 상태만 잘못될 수 있습니다.

왜 이 문제가 발생했나요?음, 분명한 사실은 여러분의 클래스가 다룰 준비가 되지 않은 이니셜라이저를 처리하는 것이 항상 중요했다는 것입니다(즉, Objective-C에서는 제가 Mac OS X 10.0에서 코코아를 프로그래밍하기 시작한 날 이후).이 점에 관한 당신의 책임에 대해 문서들은 항상 꽤 명확했습니다.하지만 우리 중 몇 명이나 그것들을 완벽하게, 그리고 글자 그대로 수행하려고 노력했을까요?아마 우리 중 아무도 아닐 거야!그리고 컴파일러는 그것들을 강요하지 않았습니다. 그것은 모두 순전히 관습적인 것이었습니다.

예를 들어 Objective-C 뷰 컨트롤러 서브클래스에서 이 지정된 이니셜라이저를 사용하는 경우:

- (instancetype) initWithCollection: (MPMediaItemCollection*) coll;

아이템 컬렉션을 할 수 .실제 미디어 아이템 컬렉션을 건네주는 것이 중요합니다.이치노 나는 "stopperinit대신.1개 썼어야 했는데(사실, 제대로 말하면, 나는 의 실장을 썼어야 했다)initWithNibName:bundle:계승된 지정 이니셜라이저)입니다만, 귀찮아서 「알고 있다」라고 하는 것은, 자신의 클래스를 그렇게 잘못 초기화하는 일이 없기 때문입니다.이 때문에 구멍이 뚫렸다.Objective-C에서는 베어본(Bare-bone)을 호출할 수 있습니다.init내 주사기를 초기화하지 않은 채로 놔두고 우린 노를 젓지 못한 채 곤경에 빠졌어

대부분의 경우 스위프트는 나를 나 자신으로부터 구해준다.이 앱을 Swift로 번역하자마자 모든 문제가 사라졌습니다.빨리! ifinit(collection:MPMediaItemCollection)된 유일한 수 . 베어본 호출로 초기화할 수 없습니다.init()★★★★★★★★★★★★★★★★★!

은 단지 입니다.init(coder:)으로 이 올 수 수 되면 nib가 로드되면 nib가 로드됩니다.니브가 로드되면init(coder:) 합니다.따라서 컴파일러는 스토퍼를 명시적으로 작성하도록 합니다.리고아아 옳옳옳옳옳

더하다

required init(coder aDecoder: NSCoder!) {
  super.init(coder: aDecoder)
}

언급URL : https://stackoverflow.com/questions/25126295/class-does-not-implement-its-superclasss-required-members

반응형