2015-07-03 33 views
6

Benhızlı ayarlayıcı neden exc_bad_access

import Foundation 

public class UsefulClass: NSObject{ 
    var test:NSNumber{ 
     get{return self.test} 
     set{ 
      println(newValue) 
      self.test = newValue 
     } 
    } 
    override init() { 
     super.init() 
     self.test = 5; 
    } 
} 

altında basit bir sınıf var ve burada

import UIKit 

class ViewController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     var testClass = UsefulClass() 
    } 
} 

başlatılıyor ediyorum Ama nedeniyle EXC_BAD_ACCESS koduna çökmesini sonra dışarı baskı 200 5s ve xcode sonuçlanır = 2. Neden bu oluyor?

cevap

7

@vadian, cevabında, sorununuzu çözmesi gereken bir çözüm sağladı. Neler olduğunu açıklamama izin ver.

Hesaplanan özellik, yani değişken tarafından desteklenmeyen bir özellik oluşturdunuz; bunun yerine, hem bir değer hem de yeni bir değer döndürmek için, hem başka bir depolanmış özellikte hem de alıcı ve ayarlayıcı bir işlem gerçekleştirirsiniz değer.

Bu bilgisayarlı özelliktir:

return self.test 

Ne yapar: alıcı uygulanmasını

var test: NSNumber { 
    get { return self.test } 
    set { 
     println(newValue) 
     self.test = newValue 
    } 
} 

bak? Geçerli örneğin test özelliğini okur ve döndürür. test özelliği nedir? Bu şu: Bu aynı özelliktir. Alıcınızın yaptığı, çalışma zamanında bir çarpışma gerçekleşene kadar, özyinelemeli ve süresiz olarak çağırmaktır.

aynı kural setter için geçerlidir:

self.test = newValue 

o uygulama kilitlenmeleri kadar kendini çağırma tutar.

+0

Gördüğünüz gibi, başka bir depolanmış özellik olmadan set {self.test = newValue - 7} gibi bir şey yapmak için Swift'deki ayarlayıcıyı geçersiz kılma yolu yok mu? – user3211122

+0

Oh nvm, http://stackoverflow.com/questions/24006234/what-is-the-purpose-of-willset-and-didset-in-swift gerçekten yardımcı oldu. Yani set/get sadece yöntemler ve didSet/willSet ivarlara bağlanır. – user3211122

3

Swift değişkenleri varsayılan olarak sentezlenen özelliklerdir. Bu yeterlidir Çoğu durumda bir değişken ayarlandıktan sonra bir şeyler yapmak gerekiyorsa kodunuzu tarafından değişkeni kalıcı ayarlar

var test: Int { 
    didSet{ 
     println("\(oldValue) - \(newValue)") 
    } 
} 

kullanın

var test: Int 

override init() { 
    super.init() 
    test = 5 
} 

(o Swift türlerini tercih önerilir) setter çağıran diziyi çağıran hangi…