치명적 오류 : 클래스에 구현되지 않은 초기화 프로그램 'init (coder :)'사용


156

Swift와 함께 남은 프로젝트를 계속하기로 결정했습니다. UIViewcontroller스토리 보드보기 컨트롤러에 사용자 정의 클래스 (서브 클래스 )를 추가하고 프로젝트를로드하면 앱이 갑자기 다음 오류와 함께 충돌합니다.

치명적 오류 : 클래스에 구현되지 않은 초기화 프로그램 'init (coder :)'사용

이것은 코드입니다.

import UIKit

class TestViewController: UIViewController {

    init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        // Custom initialization
    }

    override func viewDidLoad() {
        super.viewDidLoad()
              // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    /*
    // #pragma mark - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
        // Get the new view controller using [segue destinationViewController].
        // Pass the selected object to the new view controller.
    }
    */
}

무언가를 제안하십시오

답변:


207

발행물

이는 init?(coder aDecoder: NSCoder)대상에 이니셜 라이저가 없기 때문입니다 UIViewController. 이 메소드는 호출 UIViewController에서 a를 인스턴스화하기 때문에 필요 UIStoryboard합니다.

우리는 초기화하는 방법을 보려면 UIViewControllerA로부터 UIStoryboard, 살펴 보시기 바랍니다 여기

Objective-C에서 이것이 왜 문제가되지 않습니까?

때문에 오브젝티브 C는 자동으로 필요한 모든 상속 UIViewController초기화합니다.

왜 Swift가 자동으로 이니셜 라이저를 상속하지 않습니까?

스위프트 는 기본적으로 안전 때문에 이니셜 라이저를 상속하지 않습니다. 그러나 모든 속성에 값이 있거나 (선택 사항) 하위 클래스가 지정된 초기화기를 정의하지 않은 경우 수퍼 클래스에서 모든 초기화자를 상속합니다.


해결책

1. 첫 번째 방법

init?(coder aDecoder: NSCoder)대상에서 수동 구현UIViewController

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

2. 두 번째 방법

init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?)대상에서 제거 UIViewController하면 Dave Wood 가 아래 답변에서 지적한 것처럼 수퍼 클래스에서 필요한 모든 초기화 프로그램이 상속 됩니다.



4
고마워 빠른 후속 조치 ... TableViewController 파일을 만들 때 Xcode에 이미 두 개의 초기화 함수 init(style: UITableViewStyle) { super.init(style: style) // Custom initialization } 가있는 이유 는 무엇 입니까? 그리고 왜 Apple이 기본적으로 두 번째 init를 포함하지 않는지 알고 있습니까?
Trevor McKendrick

이것은 iOS 7 또는 iOS 8과 관련이 없습니다. 이것은 Swift가 intitializer를 상속받는 방식과 관련이 있습니다!
Sulthan

public init (view : UIViewController, frame : CGRect) {self.viewController = view self.imageName = ""self.actionName = ""super.init (frame : frame)}
scrainie

첫 번째 방법은 효과가있었습니다! 내 동적 테이블은 마침내 동적 셀로 채워졌습니다 !!! 라인이 fatalError( "init(coder:) has not been implemented")내 앱을 중지 했기 때문에 모두 .
Jose Manuel Abarca Rodríguez

25

@ 3r1d 이외의 다른 옵션은 클래스에서 다음 init 메소드를 대신 제거하는 것입니다.

init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
    super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    // Custom initialization
}

해당 init 메소드를 포함하면 서브 클래스 init(coder aDecoder: NSCoder!)가 슈퍼 클래스 를 상속받지 못하게 됩니다. 포함하지 않으면 수업은 두 가지를 모두 상속받습니다.

참고 : 자세한 내용은 약 33:50 표시의 WWDC 2014 세션 403 "중간 스위프트"를 참조하십시오.


세션 403에 대한 설명을 지적 해 주셔서 감사합니다. 그러나 자식 클래스에 편의 초기화 만있는 경우 수퍼 클래스 초기화를 상속합니까?
jamiltz

1
예. 고유 한 지정된 init 메소드 (super inits를 호출하는 메소드)를 제공하는 경우에만 수퍼 클래스 init 메소드가 상속되지 않습니다. 그런 다음 클래스에 추가하고 (3r1d의 답변과 같이) 슈퍼 버전을 호출하여 지원할 수있는 수퍼 이니셜을 지정해야합니다.
Dave Wood

자식 클래스에 (지정된) init ()없이 편리한 init () 만 있으면 컴파일 오류가 발생합니다. 편의 init () 함수는 함수 정의 내에서 self.init ()를 호출해야하기 때문입니다.
Ohmy

@narumolPug 잘못되었습니다. 지정된 init방법 을 포함시킬 필요는 없습니다 . 자녀 클래스는 수퍼 클래스에서 상속됩니다. 여전히 self.init()슈퍼 버전을 실행할 전화 를 걸 수 있습니다 .
Dave Wood

비디오의 정확한 순간은 youtu.be/W1s9ZjDkSN0?t=2030
Honey

10

swift와 동일한 문제가있는 사람들을 위해 UICollectionViewCells@ 3r1d UICollectionViewCell가 View Controller가 아닌 사용자 정의 클래스에 제안한 코드를 추가하십시오 .

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

어떤 UICollectionViewCell을 언급하고 있습니까? 코더를 이용한 초기화는 viewController를 초기화하는 방법입니다
E-Riddie

이 예제는 아니지만 누구나 문제가있는 경우 (내가 했음) ... UICollectionViewController를 사용하려고하면 사용자 정의 셀 .swift 파일에서 코더로 초기화해야합니다.
Nick Yap

2
이 인스턴스화 방법을 사용할 때
마다이

3

Swift에서 코드가 필요한 사람들을 위해 :

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

[편집] 구 버전의 스위프트를위한 ​​것입니다. 아마도 더 이상 작동하지 않을 것입니다.


3

나는 프로그래밍 방식의 collectionView 셀 에서이 문제를 겪었지만 op가 vc에 대해 묻는 경우에도 답변을 검색 할 때이 질문에 착륙했습니다. 나를 위해 문제는 내가했다

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

최고의 답변이 작동하지 않도록 구현했습니다. 내가 셀에 없었던 것은 이니셜 라이저였습니다.

// my programmatic cell was missing this
override init(frame: CGRect) {
    super.init(frame: frame)
}

추가하면 오류가 사라졌습니다.


1

내부 메커니즘이 제대로 작동하도록 몇 가지 메소드를 추가하는 대신 내 속성을 @lazy로 정의하고 클래스 범위에서 바로 초기화합니다.


를 통해 속성을 선택 사항으로 선언 할 수도 있습니다 ?.
Julian B.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.