2014-10-17 90 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