将UIGestureRecognizers附加到封装的UIViews

时间:2013-05-05 02:47:07

标签: ios objective-c uigesturerecognizer

我对UITapGestureRecognizer有一个奇怪的问题,当我要调用它的动作时,我总是会抛出崩溃或异常(无法识别的选择器)。我之前使用过手势识别器,但这次我将它附加到UIView,这是NSObject的属性(我使用对象的方法构建视图)。以下是我正在做的最小例子:

MyObject.h:

#import <Foundation/Foundation.h>
@interface MyObject : NSObject
@property (nonatomic, strong) UIView *aView;
- (void)createViewWithFrame:(CGRect)frame;
@end

MyObject.m:

@interface MyObject ()
- (void)tapped:(id)sender; // Non-specific id type for brevity
@end

@implementation MyObject

- (void)tapped:(id)sender {
    NSLog(@"Tapped");
}

- (void)createViewWithFrame:(CGRect)frame {

    _aView = [[UIView alloc] initWithFrame:frame];
    self.aView.backgroundColor = [UIColor blueColor];
    self.aView.userInteractionEnabled = YES;
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
                                    initWithTarget:self
                                    action:@selector(tapped:)];

    [self.aView addGestureRecognizer:tap];

}

ViewController.m:

- (void)viewDidAppear:(BOOL)animated {

    [super viewDidAppear:animated];

    MyObject *obj = [[MyObject alloc] init];
    [obj createViewWithFrame:self.view.frame]; // Excuse poor frame - example only

    [self.view addSubview:obj.aView];
}

然后,当我点击视图时,应用程序在这里崩溃:

libobjc.A.dylib`objc_msgSend:
0x10e008c:  movl   8(%esp), %ecx
0x10e0090:  movl   4(%esp), %eax
0x10e0094:  testl  %eax, %eax
0x10e0096:  je     0x10e00e8                 ; objc_msgSend + 92
0x10e0098:  movl   (%eax), %edx
0x10e009a:  pushl  %edi
0x10e009b:  movl   8(%edx), %edi ; Thread 1: EXC_BAD_ACCESS (code=2, address=0x9)
0x10e009e:  pushl  %esi
0x10e009f:  movl   (%edi), %esi
0x10e00a1:  movl   %ecx, %edx

确切的崩溃点会有所不同,我偶尔会收到无效的选择器错误。 NSLog当然不会发生。我之前(成功)使用过手势识别器,这让我相信问题出在我的设置/设计中。任何人都可以解释为什么手势识别器在这种情况下无法正常工作吗?

1 个答案:

答案 0 :(得分:1)

问题在于MyObject的范围,全局声明变量,

@property(nonatomic, strong) MyObject *obj;

在你的viewDidAppear中,初始化并添加视图

self.obj = [[MyObject alloc] init];
[self.obj createViewWithFrame:self.view.frame]; 
[self.view addSubview:self.obj.aView];

就是这样。

现在它正在工作!!

问题是什么?,* MyObject obj的范围以viewDidAppear方法结束。 当识别出水龙头时,它正在寻找触发给定方法的对象。但目标不在那里。