0

我用不是当前对象的目标创建了一个 UITapGesture。后来,当点击时,应用程序崩溃。

查看控制器.h:

@interface ViewController : UIViewController
{
    IBOutlet UIImageView *iv;
}
@end

查看控制器.c:

#import "ViewController.h"
#import "Target.h"

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    Target *t = [[Target alloc] init];
    UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:t action:@selector(gestureDone:)];
    [iv addGestureRecognizer:tgr];
    [iv setUserInteractionEnabled:YES];
}

@end

目标.h:

@interface Target : NSObject

- (void)gestureDone:(UIGestureRecognizer *)gr;

@end

目标.c:

@implementation Target

- (void)gestureDone:(UIGestureRecognizer *)gr
{
    NSLog(@"Gesture!");
}

@end

(我的 XIB 文件只包含一张图片......)点击图片时,它会崩溃。例如,如果我将实例变量 Target *t 添加到我的视图控制器(并删除 viewDidLoad 中的本地声明),则不会出现问题。当不这样做时,我在 Target 中覆盖了 dealloc,在其中放置了一个 NSLog,并看到 viewDidLoad 完成执行后,Target 对象就变成了 fred。

我做错了什么,还是有问题?(通常我不会遇到这个问题,因为我使用 initWithTarget:self ...)。

4

2 回答 2

8

UIGestureRecognizer不保留其目标。大多数采用目标/动作对的对象不保留其目标。这在Cocoa Fundamentals Guide /Communicating with Objects/The Target-Action Mechanism/The Target中提到:

控制对象不(也不应该)保留它们的目标。但是,发送动作消息的控件的客户端(通常是应用程序)负责确保它们的目标可用于接收动作消息。为此,他们可能必须将目标保留在内存管理的环境中。此预防措施同样适用于代表和数据源。

您需要确保以其他方式保留目标,例如通过将引用存储tViewController.

于 2013-02-13T00:10:09.367 回答
0

Add an instance variable of the Target t to your ViewController class and make it strong. That way it stays in memory.

于 2013-02-13T08:01:09.593 回答