点击未保留的手势目标(使用ARC)

时间:2013-02-12 23:56:19

标签: ios objective-c automatic-ref-counting gesture

我创建了一个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

Target.h:

@interface Target : NSObject

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

@end

Target.c:

@implementation Target

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

@end

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

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

2 个答案:

答案 0 :(得分:8)

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

中提到
  

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

您需要确保以其他方式保留目标,例如在t的实例变量中存储对ViewController的引用。

答案 1 :(得分:0)

将目标t的实例变量添加到ViewController类并使其变强。这样它就会留在记忆中。