'ViewController' sınıfının hızlı bir şekilde başlatıcısı yok


123

Bunu yaparken derleyiciden şikayet alıyorum

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) {
    }
}

Ancak, eklersem ? AppDelegate'in sonunda aşağıdaki gibi ve hata giderildi .

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) {
    }
}

optionalYanılmıyorsam bu hatayla alakalı anahtar kelime görmüyorum .

Yanıtlar:


240

Hata düzeltilebilir, ancak ilk sürümünüzle ilgili sorun, delegatevarsayılan değeri olmayan bir üye değişkeninizin olmasıdır. Swift'deki tüm değişkenlerin her zaman bir değeri olmalıdır. Bu, onu sahip olmadığınız bir başlatıcıda ayarlamanız gerektiği veya satır içi varsayılan bir değer sağlayabileceğiniz anlamına gelir.

Bunu isteğe bağlı yaptığınızda, nilvarsayılan olarak olmasına izin vererek, ona açıkça bir değer verme veya onu başlatma ihtiyacını ortadan kaldırırsınız.


45

Swift Programlama Dili şunları belirtir:

Sınıflar ve yapılar, depolanan özelliklerinin tümünü, o sınıfın veya yapının bir örneği yaratıldığında uygun bir başlangıç ​​değerine ayarlamalıdır. Saklanan özellikler belirsiz bir durumda bırakılamaz.

Bir başlatıcı içinde depolanmış bir özellik için bir başlangıç ​​değeri ayarlayabilir veya özelliğin tanımının bir parçası olarak bir varsayılan özellik değeri atayabilirsiniz.

Bu nedenle şunları yazabilirsiniz:

class myClass {

    var delegate: AppDelegate //non-optional variable

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

}

Veya:

class myClass {

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

    init() {
        println("Hello")
    }

}

Veya:

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
    }

}

Ancak şunu yazamazsınız:

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

Bazen bu hata, kullanıma hazırlanmamış bir var veya izniniz olduğunda da görünür.

Örneğin

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

Değişkeninizin ne yapması gerektiğine bağlı olarak, bu var türünü isteğe bağlı olarak ayarlayabilir veya aşağıdaki gibi bir değerle başlatabilirsiniz.

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
}

peki bunun çözümü nedir?
Martian2049

bunun yerine bir init işlevinde başlatılabilirler mi?
Martian2049

13

Bu sorun genellikle değişkenlerinizden birinin değeri olmadığında veya "!" Eklemeyi unuttuğunuzda ortaya çıkar. bu değişkeni ayarlanana kadar nil depolamaya zorlamak.

Sizin durumunuzda sorun burada:

var delegate: AppDelegate

var delegate: AppDelegate!Sıfır depolayan ve değer kullanılana kadar değişkeni sarmayan bir isteğe bağlı olacak şekilde tanımlanmalıdır .

Xcode'un, buna neden olan belirli bir kod satırını vurgulamak yerine tüm sınıfı bir hata olarak vurgulaması üzücü, bu yüzden anlamak biraz zaman alıyor.


Bu, bir IBOutlet durumunda benim için hata mesajından kurtuluyor, ancak standart bir değişken durumunda değil.
Tim Vermeulen

Bu benim sorunumu çözdü. Bunu yapmaya çalıştığımda: var fetchedResultsController: NSFetchedResultsController Derleme hatası aldım. Toplayarak "!" var fetchedResultsController: NSFetchedResultsController gibi hata ortadan kalktı!
Jervisbay

senin için teşekkürler! Bu benim için çok yararlı, ben sadece "?" isteğe bağlı değere ancak "!" Daha önce bilmiyordum "!" bunun gibi: var time: NSTimer!
AmyNguyen

10

bir "!" kaybettiyseniz kodunuzda, aşağıdaki kod gibi, bu hatayı da alırsınız.

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

Yorumlu ikinci satırda ima var appDelegate : AppDelegate?edildiği let appDelegate = UIApplication.sharedApplication().delegategibi ile değiştirin viewDidLoad().

Anahtar kelime "isteğe bağlı" kullanımına tam olarak ifade eder ?, bakınız bu daha fazla ayrıntı için.


1

Xcode 7 ve Swift 2 kullanıyorum. Son olarak:

class ViewController: UIViewController {var time: NSTimer // burada hata var}

Sonra düzeltirim: 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)
}

}


Cevabınızda netlik tam olarak orada değil, ama bu benim sorunumdu; Bir üye var opsiyonunu belirtmedim (zorunlu / isteğe bağlı); Bir kez yaptım ve kodu daha sonra ayarladım, ViewController artık bir başlatıcıya sahip olmadığından şikayet etmedi.
James Perih

0

Benim için eksik bir beyandı. Örneğin:

var isInverted: Bool

Bunun yerine doğru yol:

var isInverted: Bool = false
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.