我在工作中遇到了一个重大问题,非常感谢您的帮助。这已经花费了我 2 天时间。
我想要做的是让一个特殊的图像类触发它,当它被触摸时它被分配回调。就是这样。
但是当我触摸图像时它崩溃了,通常没有错误消息只是 (lldb)。有时它会说像 [__NSCFData tapped:]: unrecognized selector sent to instance 0x1780af360" 这样的垃圾。有时它会显示 “发送到释放对象的消息”。
我可以连续运行该应用 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 tap 事件监听器
@objc func tapped(tap:UITapGestureRecognizer)
{
println("here")
if(_touchCallback != nil)
{
touchCallback(self)
}
}
然后代码工作并触发触摸事件(在 K_PreviewImage 和 Controller 回调函数“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' 的引用,即使添加了 subview ,即使它属于 k,k 也没有被保留。通过使数组存储对 K_PreviewImage 而不是 iImage 的引用,编译器现在保留对 K_Preview Image 的引用
请您参考如下方法:
首先,您似乎正在尝试将图像添加为 subview 。我不太了解 Swift,但是 _view.addSubview(k.image) 对我来说看起来不对,而且作为 _view.addSubview(k) 会更有意义。
其次,您没有保留对 K_PreviewImage 的引用。您将 k.image 指定为 subview ,这会导致 k 被系统检测为“不再使用”。它会清理它,当您尝试访问它时,您会崩溃。
