치명적 오류 : 클래스에 구현되지 않은 초기화 프로그램 '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.