私がこれをしているときコンパイラーから苦情を得る
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
キーワードがこのエラーに関連しているとは思われません。
エラーは改善される可能性がありますが、最初のバージョンの問題は、デフォルト値を持たないメンバー変数delegate
があることです。 Swiftのすべての変数は常に値を持つ必要があります。それはあなたが持っていない初期化子でそれを設定しなければならないか、インラインでそれにデフォルト値を提供することができることを意味します。
オプションにすると、デフォルトでnil
になります。明示的に値を指定したり初期化したりする必要がなくなります。
Swift Programming Language次のように述べています。
クラスと構造体は、そのクラスまたは構造体のインスタンスが作成されるまでに、格納されているすべてのプロパティを適切な初期値に設定する必要があります。保存されたプロパティは不確定な状態のままにすることはできません。
イニシャライザでストアドプロパティの初期値を設定するか、プロパティの定義の一部としてデフォルトのプロパティ値を割り当てることができます。
したがって、あなたは書くことができます:
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
}
}
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
}
この問題は通常、変数の1つに値がない場合、または「!」を追加し忘れた場合に発生します。設定されるまでこの変数にnilを格納させる。
あなたの場合、問題はここにあります:
var delegate: AppDelegate
Nilを格納し、その値が使用されるまで変数をアンラップしないオプションにするには、var delegate: AppDelegate!
として定義する必要があります。
Xcodeが原因となった特定のコード行を強調表示するのではなく、クラス全体をエラーとして強調表示するのは悲しいことなので、それを理解するにはしばらく時間がかかります。
「!」をなくした場合以下のコードのように、コード内でこのエラーが発生することもあります。
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)
}
}
let appDelegate = UIApplication.sharedApplication().delegate
の2行目のコメント行に示されているように、var appDelegate : AppDelegate?
をviewDidLoad()
に置き換えます。
キーワード "optional"は?
の使用を正確に指しています。詳細は this を参照してください。
私はXcode 7とSwift 2を使っています。
クラスViewController:UIViewController {var time:NSTimer //ここにエラーが発生しました}
それから私は修正します:クラス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 isInverted: Bool
代わりに正しい方法:
var isInverted: Bool = false