【发布时间】:2014-10-17 17:38:46
【问题描述】:
我在工作中遇到了一个大问题,非常感谢一些帮助。这已经花费了我 2 天的时间。
我想要做的是让一个特殊的图像类触发它,当它被触摸时它被分配回调。就是这样。
但是当我触摸图像时它崩溃了,通常没有错误消息(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)
}
}
然后代码 WORKS 并触发触摸事件(在 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 来触发回调而不是给我一个不清楚的“释放”内存崩溃?
我的第二个问题是为什么当我将变量从成员变量移动到函数变量时会再次导致崩溃。如果对象被释放,它一开始就听不到点击事件,可以吗?为什么还会出现在荧幕上?为什么它只是因为它不是成员变量而被解除分配!
我怎么能动态地创建一个自定义对象并让它触发点击事件!
更新
这是完整的代码块,涉及如何通过触摸事件添加我的 K_PreviewImage
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")
}
已解决:
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_PreviewImage 'k' 的引用,即使它属于 k,k 也没有被保留。通过使数组存储对 K_PreviewImage 而不是 iImage 的引用,编译器现在保留对 K_Preview Image 的引用
【问题讨论】:
标签: ios uiview swift uigesturerecognizer nszombies