'ViewController'클래스에는 신속하게 이니셜 라이저가 없습니다.


123

이 작업을 수행 할 때 컴파일러로부터 불만 사항 받기

class ViewController: UIViewController {

    var delegate : AppDelegate
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //self.appDelegate = UIApplication.sharedApplication().delegate;

    }

    @IBAction func getData(sender : AnyObject) {

    }

    @IBAction func LogOut(sender : AnyObject) {
    }
}

그러나 내가 추가하면 ? AppDelegate 의 끝에서 아래와 같이 오류가 사라졌습니다.

class ViewController: UIViewController {

    var delegate : AppDelegate?
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        //self.appDelegate = UIApplication.sharedApplication().delegate;

    }

    @IBAction func getData(sender : AnyObject) {

    }

    @IBAction func LogOut(sender : AnyObject) {
    }
}

내가 optional틀리지 않는 한이 오류와 관련된 키워드 가 보이지 않습니다 .

답변:


239

오류가 개선 될 수 있지만 첫 번째 버전의 문제점 delegate은 기본값이없는 멤버 변수가 있다는 것입니다. Swift의 모든 변수에는 항상 값이 있어야합니다. 즉, 가지고 있지 않은 이니셜 라이저에서 설정해야하거나 기본값을 인라인으로 제공 할 수 있습니다.

선택 사항으로 만들면 nil기본적으로 허용 하여 명시 적으로 값을 제공하거나 초기화 할 필요가 없습니다.


45

Swift 프로그래밍 언어 는 다음과 같이 말합니다.

클래스 및 구조는 해당 클래스 또는 구조의 인스턴스가 생성 될 때까지 저장된 모든 속성을 적절한 초기 값으로 설정해야합니다. 저장된 속성은 불확실한 상태로 남을 수 없습니다.

이니셜 라이저 내에서 저장된 속성에 대한 초기 값을 설정하거나 속성 정의의 일부로 기본 속성 값을 할당 할 수 있습니다.

따라서 다음과 같이 작성할 수 있습니다.

class myClass {

    var delegate: AppDelegate //non-optional variable

    init() {
        delegate = UIApplication.sharedApplication().delegate as AppDelegate
    }

}

또는:

class myClass {

    var delegate = UIApplication.sharedApplication().delegate as AppDelegate //non-optional variable

    init() {
        println("Hello")
    }

}

또는:

class myClass {

    var delegate : AppDelegate! //implicitly unwrapped optional variable set to nil when class is initialized

    init() {
        println("Hello")
    }

    func myMethod() {
        delegate = UIApplication.sharedApplication().delegate as AppDelegate
    }

}

그러나 다음은 작성할 수 없습니다.

class myClass {

    var delegate : AppDelegate //non-optional variable

    init() {
        println("Hello")
    }

    func myMethod() {
        //too late to assign delegate as an non-optional variable
        delegate = UIApplication.sharedApplication().delegate as AppDelegate
    }

}

22

때때로이 오류는 초기화되지 않은 var 또는 let이있을 때도 나타납니다.

예를 들면

class ViewController: UIViewController {
    var x: Double
    // or
    var y: String
    // or
    let z: Int
}

변수가 수행해야하는 작업에 따라 해당 var 유형을 선택 사항으로 설정하거나 다음과 같은 값으로 초기화 할 수 있습니다.

class ViewController: UIViewCOntroller {
    // Set an initial value for the variable
    var x: Double = 0
    // or an optional String
    var y: String?
    // or
    let z: Int = 2
}

그래서 이것에 대한 해결책은 무엇입니까?
Martian2049

대신 init 함수에서 초기화 할 수 있습니까?
Martian2049

13

이 문제는 일반적으로 변수 중 하나에 값이 없거나 "!"를 추가하는 것을 잊었을 때 나타납니다. 이 변수가 설정 될 때까지 nil을 저장하도록 강제합니다.

귀하의 경우 문제는 여기에 있습니다.

var delegate: AppDelegate

var delegate: AppDelegate!nil을 저장하는 옵션으로 만들고 값이 사용될 때까지 변수를 풀지 않도록 정의해야합니다 .

Xcode가 전체 클래스를 원인이 된 특정 코드 줄을 강조 표시하는 대신 오류로 강조 표시하는 것이 슬프기 때문에이를 파악하는 데 시간이 걸립니다.


이것은 IBOutlet의 경우 오류 메시지를 제거하지만 표준 변수의 경우에는 제거하지 않습니다.
Tim Vermeulen 2015

이것은 내 문제를 해결합니다. 이렇게하려고 할 때 : var fetchedResultsController : NSFetchedResultsController 컴파일 오류가 발생했습니다. 추가하여 "!" var fetchedResultsController : NSFetchedResultsController!와 같이 오류가 사라졌습니다.
Jervisbay

ur ans 주셔서 감사합니다! 이것은 나에게 안타까운 일이다. 나는 방금 "?"를 알고 있었다. 선택적 값이지만 "!" 나는 전에 알지 못했다. 나는 "!" 이렇게 : var time : NSTimer!
AmyNguyen

10

"!"를 잃어버린 경우 아래 코드와 같이 코드에서이 오류가 발생합니다.

import UIKit

class MemeDetailViewController : UIViewController {

    @IBOutlet weak var memeImage: UIImageView!

    var meme:Meme! // lost"!"

    override func viewWillAppear(animated: Bool) {

        super.viewWillAppear(animated)
        self.memeImage!.image = meme.memedImage
    }

    override func viewDidDisappear(animated: Bool) {
        super.viewDidDisappear(animated)
    }

}

3

교체 var appDelegate : AppDelegate?let appDelegate = UIApplication.sharedApplication().delegate두 번째 주석 줄에 암시로 viewDidLoad().

키워드는 "선택 사항"의 사용을 정확히 의미 ?, 볼 자세한 내용은.


1

Xcode 7과 Swift 2를 사용합니다. 마지막으로 다음을 만들었습니다.

class ViewController : UIViewController {var time : NSTimer // error this here}

그런 다음 수정합니다 : class ViewController : UIViewController {

var time: NSTimer!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

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

override func viewWillAppear(animated: Bool) {
    //self.movetoHome()
    time = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: #selector(ViewController.movetoHome), userInfo: nil, repeats: false)
    //performSegueWithIdentifier("MoveToHome", sender: self)
    //presentViewController(<#T##viewControllerToPresent: UIViewController##UIViewController#>, animated: <#T##Bool#>, completion: <#T##(() -> Void)?##(() -> Void)?##() -> Void#>)
}

func movetoHome(){
    performSegueWithIdentifier("MoveToHome", sender: self)
}

}


명확성은 당신의 대답에 전부는 아니지만 이것이 내 문제였습니다. 멤버 var의 옵션 (강제 / 옵션)을 지정하지 않았습니다. 한 번 수행하고 나중에 코드를 조정하면 ViewController가 더 이상 이니셜 라이저가 없다고 불평하지 않았습니다.
James Perih 2016-06-17

0

저에게는 불완전한 선언이었습니다. 예를 들면 :

var isInverted: Bool

대신 올바른 방법 :

var isInverted: Bool = false
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.