Swift의 UIViewController에서 기본 super.init ()를 호출 할 수없는 이유는 무엇입니까?


84

UIViewController스토리 보드에서를 사용하지 않고 일부 개체를 init전달 하는 사용자 지정 함수 를 갖고 싶습니다 NSManagedObjectID. super.init()Objective-C 에서처럼 전화하고 싶습니다. 이렇게 :

init(objectId: NSManagedObjectID) {
    super.init()
}

하지만 다음과 같은 컴파일러 오류가 발생합니다.

수퍼 클래스 UIViewController의 지정된 이니셜 라이저를 호출해야합니다.

더 이상 이렇게하지 않아도 되나요?

답변:


119

에 대해 지정된 이니셜 라이저는 UIViewController입니다 initWithNibName:bundle:. 대신 그것을 호출해야합니다.

참조 http://www.bignerdranch.com/blog/real-iphone-crap-2-initwithnibnamebundle-is-the-designated-initializer-of-uiviewcontroller/를

펜촉 nil이 없으면 nibName을 전달 하십시오 (번들도 선택 사항입니다). 그런 다음에 사용자 지정보기를 만들 수 있습니다 loadView하거나 하위 뷰를 추가하여 self.viewviewDidLoad당신이 사용하는 동일로.


4
그래서 현재는 펜촉이 아닌 UIViewController 하위 클래스에서 사용자 정의 초기화 메서드를 만드는 것이 불가능합니까?
SirRupertIII

1
아, 고마워 !! 펜촉 이름으로 ""를 전달했습니다.
SirRupertIII

2
아, 조금 파헤쳐 initWithCoder:본 결과 NSCoding프로토콜 에서 나온 것으로 밝혀졌습니다 ... UIViewController 인스턴스를 초기화하는 역할이 UIViewController의 "지정된"이니셜 라이저인지 또는 수퍼 클래스인지 아직 파악할 수 없습니다. .
니콜라스 미아리

6
감사! 빠른 복사 / 붙여 넣기를 위해 let속성 을 설정 한 후 다음을 호출하십시오 super.init(nibName: nil, bundle: nil).
Ferran Maylinch

3
Init With coder는 상태 복원을 수행해야 할 때 사용됩니다. 상태 복원 기능을 사용하여 뷰 컨트롤러의 상태를 저장하면 코더는 상태를 저장할 때 저장 한 값을 반환합니다. 여기에서 뷰 컨트롤러를 응용 프로그램을 닫을 때의 마지막 초기 상태로 다시 빌드 할 수 있습니다. 그들은에서 중단의 사용자에게 그래서
Esko918

44

또 다른 좋은 해결책은 convenience다음과 같이 새 이니셜 라이저를 이니셜 라이저로 선언하는 것입니다 .

convenience init( objectId : NSManagedObjectID ) {
    self.init()

    // ... store or user your objectId
}

하위 클래스에서 지정된 이니셜 라이저를 전혀 선언하지 않으면 자동으로 상속되며 self.init()편리한 이니셜 라이저 내 에서 사용할 수 있습니다.

의 UIViewController의 경우 기본 init 메소드 호출 init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!)nil두 인수 (의 UIViewController에 명령을 클릭하면 그 정보를 줄 것이다)합니다.

TL; TR : UIViewControllers 로 프로그래밍 방식으로 작업하는 것을 선호하는 경우 여기에 사용자 지정 인수가있는 새 이니셜 라이저를 추가하는 완전한 작업 예제가 있습니다.

class MyCustomViewController: UIViewController {
    var myString: String = ""

    convenience init( myString: String ) {
        self.init()

        self.myString = myString
    }
}

이것은 더 우아한 솔루션이며 어떤 일반적인 경우에 작동
치프 리안

2
나는 이것을 확장에서 시도했고, 그것은 재귀 적으로 자신을 불렀다.
Danyal Aytekin 2015 년

12
이 답변에 "트릭은"그가있다 myString로 설정되어 ""이 때문에 init필요하지 않습니다. 이 솔루션은 초기 값을 사용하지 않으려면 분리 self.init(nibName: nil, bundle:nil)
되며이

2
@Yar하거나 할 myString속성을 선택
클라스

1
@Klaas 예 : 내 문제는 선택 사항을 피하고 코드를 컴파일하기 위해서만 이니셜 라이저를 사용하고 있다는 것입니다.
Dan Rosenstark 2015 년

16

occulus의 답변 을 개선하려면 :

init() {
     super.init(nibName: nil, bundle: nil)
}

15

업데이트 : 링크 추가

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621359-init

iOS 문서에 따르면 UIViewController에 지정된 이니셜 라이저는 initWithNibName: bundle:.

UIViewController를 하위 클래스로 만드는 경우 NIB를 사용하지 않더라도이 메서드의 슈퍼 구현을 호출해야합니다.

다음과 같이 할 수 있습니다.

init(objectId : NSManagedObjectID) {

    super.init(nibName: (xib's name or nil'), bundle: nil)

   // other code...
}

또는

새 이니셜 라이저를 편의 이니셜 라이저로 선언하십시오.

 convenience init( objectId : NSManagedObjectID ) {

    self.init()

     // other code...

}


1
원본을 스크린 캡으로 남겨 두지 말고 어트 리뷰 션을 위해 원본에 연결해야합니다.
Nathan Tuggy 2017-06-24

@NcNc가 말한 것과 동일한 프로세스를 사용했습니다. 그것은 나를 위해 일했습니다. 다음의 링크
아닐 굽타

@NathanTuggy 아니, 그는해서는 안됩니다. 링크에는 언젠가 만료되거나 이동하는 기능이 있습니다. 찾고있는 정보 대신 404 오류를보고 싶은 사람은 누구입니까?
mykolaj

1
@mykolaj : 정보는 이미 여기에 있습니다. (그렇지 않으면 링크 전용 답변으로 삭제 플래그를 지정했을 것입니다.) 그러나이 글을 읽는 사람이 어디서 왔는지 알아 내고 크레딧을 제공 할 수 있도록 속성도 중요합니다. 스크린 샷은 작동하지 않지만 링크는 작동합니다. 링크가 썩 으면 안타깝지만 어떤 종류의 신용도 전혀주지 않는 것보다 더 나쁜 상황이라고 말할 수는 없습니다. SO가 링크 전용 답변에 대한 이의는 링크 전용 답변에 대한 것입니다. 링크가 아닙니다. 링크 정보는 원하는 공식입니다.
Nathan Tuggy

@NathanTuggy 방금 링크를 추가했습니다. 당신의 연상 주셔서 감사합니다
NcNc
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.