2014-10-17 89 views
1

我有一個主要問題,我堅持在工作中,並會真正感謝一些幫助。這已經花了我2天了。UITapGestureRecognizer導致崩潰與不同的錯誤消息

我想要做的是有一個特殊的圖像類火它分配回撥時,它被觸摸。而已。

但是,當我觸摸它的圖像崩潰,通常沒有錯誤信息(lldb)。有時候它說像"[__NSCFData tapped:]: unrecognized selector sent to instance 0x1780af360"這樣的垃圾。有時它說"message sent to deallocated object"

我可以連續10次運行應用程序,並且每次只是從屏幕上的同一對象中獲取這些隨機消息之一。

的代碼非常簡單:

//view controller 
var k:K_PreviewImage! 
override func viewDidLoad() 
    { 
     var image:iImage = iImage(imageName: "ja3.jpg") 
     k = K_PreviewImage(image: image) 
     k.touchCallback = nestedTap 
     _view.addSubview(k.image) 
    } 

    func nestedTap(k:K_PreviewImage) 
    { 
     println("Successs") 
    } 

這裏是內部K_PreviewImage代碼(我點擊的圖片)。這不會從任何東西繼承,包括NSObject

var touchCallback:((K_PreviewImage)->Void) 
    { 
     set{ 
      if(_touchCallback == nil) 
      { 
       var tap:UIGestureRecognizer = UITapGestureRecognizer(target: self, action:"tapped:") 
       _image.addGestureRecognizer(tap) 
      } 

      _touchCallback = newValue 
     } 
     get{ 
      return _touchCallback 
     } 

    func tapped(tap:UITapGestureRecognizer) 
    { 
     println("here") 
     if(_touchCallback != nil) 
     { 
      touchCallback(self) 
     } 
    } 

上面的代碼導致崩潰100%的時間。

如果我在K_PreviewImage添加@objc太水龍頭事件監聽器這樣

@objc func tapped(tap:UITapGestureRecognizer) 
    { 
     println("here") 
     if(_touchCallback != nil) 
     { 
      touchCallback(self) 
     } 
    } 

然後代碼工作和觸摸事件被觸發(內外K_PreviewImage和控制器回調函數「nestedTap」。

不知道爲什麼這樣的作品,但它。但我還是一個沒有小溪槳,因爲當我做K_PreviewImage函數變量代替類成員變量,我得到再次崩潰

override func viewDidLoad() 
    { 
     var image:iImage = iImage(imageName: "ja3.jpg") 
     var k:K_PreviewImage = K_PreviewImage(image: image) 
     k.touchCallback = nestedTap 
     _view.addSubview(k.image) 
    } 

所以我的第一個問題是爲什麼我需要添加@objc才能讓回調起火,而不是給我一個不明確的「釋放」的內存崩潰?

我的第二個問題是,爲什麼當我將變量從一個成員變量移動到一個函數變量時,它是否會再次導致崩潰。如果該對象被釋放,它不可能首先聽到輕敲事件嗎?爲什麼它仍然在屏幕上?爲什麼它只是因爲它不是一個成員變量纔得到分配?

我該如何動態地創建一個自定義對象並讓它觸發點擊事件!

UPDATE

下面是包括是如何被添加了觸摸事件

var _array:Array<iImage>! 

    override func viewDidLoad() 
    { 
     _array = Array<iImage>() 
     var image:iImage = iImage(imageName: "ja3.jpg") 
     var k:K_PreviewImage = K_PreviewImage(image: image) 
     k.touchCallback = nestedTap 
     _view.addSubview(k.image) 
     _array.append(k.image) 
    } 

    func nestedTap(k:K_PreviewImage) 
    { 
     println("Successs") 
    } 

解決了我的K_PreviewImage完整的代碼塊:

override func viewDidLoad() 
    { 
     _array = Array<K_PreviewImage>() 
     var image:iImage = iImage(imageName: "ja3.jpg") 
     var k:K_PreviewImage = K_PreviewImage(image: image) 
     k.touchCallback = nestedTap 
     _view.addSubview(k.image) 
     _array.append(k) 
    } 

    func nestedTap(k:K_PreviewImage) 
    { 
     println("Successs") 
    } 

,因爲我不是存儲即使添加了子視圖,即使它屬於k,也不參與K_PreviewImage'k',k不被保留。通過使數組存儲對K_PreviewImage的引用而不是iImage,編譯器現在保留對K_Preview的引用Image

回答

3

首先,它看起來像是在嘗試將圖像添加爲子視圖。我不知道斯威夫特一切都好,但_view.addSubview(k.image)看起來不對我,並會更有意義,因爲_view.addSubview(k)。其次,你不保留你的參考K_PreviewImage。您將k.image指定爲子視圖,導致k被系統檢測爲「不再使用」。它會清理它,當你嘗試訪問它時,你會崩潰。

+0

首先感謝您抽出寶貴的時間對此進行審查並給出周到的回覆。關於將K檢測爲「不再是用戶」的系統,爲什麼是這樣?我將數組K存儲在一個成員變量的數組中。通過添加I.image爲什麼系統刪除父母並保留孩子?圖像是K的成員變量!它並沒有在這個例子中顯示,但是我使用_array.append(K) – Aggressor 2014-10-17 18:22:19

+1

將K添加到視圖後將數組存儲在數組中。您是否可以更新源以反映'k'的正確範圍?因爲你遇到一個錯誤,指出['__NSCFData tapped:]'正在嘗試訪問,它看起來很像你期望的對象不是你擁有的對象 - 表示內存被釋放回到系統和一個'NSData'對象出現在它的位置。 – 2014-10-17 18:26:01

+0

非常感謝你,我明白了。我將iImage類存儲在數組引用中,但顯然不保留作爲其一部分的對象(即K_PreviewImage),但現在將數組和K_PreviewImages數組保留爲正確。謝謝你,謝謝你,謝謝你!我被困在這個好幾天了,用一個子類UIGestureTapEvent傳遞數據!現在我可以再次使用乾淨的代碼了! – Aggressor 2014-10-17 18:38:05