UITableView 中的 UIGestureRecognizer - 滚动后崩溃?
我有一个带有自定义单元格的 UITableView。每个单元格内有 2 个视图。每个视图都有一个附加的 UIGestureRecognizer 来处理点击事件。当点击视图时,我向 UINavigationController 发送一条消息以推送详细信息视图。在我实际滚动表格之前,这种情况效果很好。滚动表格后,当用户点击单元格内的视图之一时,应用程序会崩溃。例如,我可以加载应用程序,单击第二个单元格中的视图,然后将详细视图正确推送到屏幕上。从那里,我导航回到表格,滚动到底部,回到顶部,然后点击相同的视图。从那里开始,应用程序崩溃并出现无法识别的选择器错误。这是我的手势设置(在 viewDidLoad 中):
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleTap:)];
[self.view addGestureRecognizer:recognizer];
recognizer.delegate = self;
[recognizer release];
这是调用的方法:
-(void)handleTap:(UITapGestureRecognizer *)sender{
NSLog(@"Handling tap on ArticleTileViewController");
ArticleViewController *vc = [[ArticleViewController alloc] initWithArticleData:self.articleDataArray];
PROJECTAppDelegate *appDelegate = (PROJECTAppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate.navController pushViewController:vc animated:YES];
}[appDelegate.navController pushViewController:vc animated:YES];
}
最后,这是我在控制台中获得的堆栈跟踪:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType handleTap]: unrecognized selector sent to instance 0x607ba30'
*** Call stack at first throw:
(
0 CoreFoundation 0x02839b99 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0298940e objc_exception_throw + 47
2 CoreFoundation 0x0283b6ab -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x027ab2b6 ___forwarding___ + 966
4 CoreFoundation 0x027aae72 _CF_forwarding_prep_0 + 50
5 UIKit 0x0057f060 -[UIGestureRecognizer _updateGestureWithEvent:] + 727
6 UIKit 0x0057b8bf -[UIGestureRecognizer _delayedUpdateGesture] + 47
7 UIKit 0x00580152 _UIGestureRecognizerUpdateObserver + 637
8 UIKit 0x00581464 _UIGestureRecognizerUpdateGesturesFromSendEvent + 51
9 UIKit 0x0032a844 -[UIWindow _sendGesturesForEvent:] + 1292
10 UIKit 0x003263bf -[UIWindow sendEvent:] + 105
11 UIKit 0x00309cb4 -[UIApplication sendEvent:] + 447
12 UIKit 0x0030e9bf _UIApplicationHandleEvent + 7672
13 GraphicsServices 0x02f07822 PurpleEventCallback + 1550
14 CoreFoundation 0x0281aff4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
15 CoreFoundation 0x0277b807 __CFRunLoopDoSource1 + 215
16 CoreFoundation 0x02778a93 __CFRunLoopRun + 979
17 CoreFoundation 0x02778350 CFRunLoopRunSpecific + 208
18 CoreFoundation 0x02778271 CFRunLoopRunInMode + 97
19 GraphicsServices 0x02f0600c GSEventRunModal + 217
20 GraphicsServices 0x02f060d1 GSEventRun + 115
21 UIKit 0x00312af2 UIApplicationMain + 1160
22 PROJECT 0x00002459 main + 121
23 PROJECT 0x000023d5 start + 53
24 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException
'
编辑:经过一段时间的测试后,我确定只有当时屏幕上可见的视图才会触发该事件。其他一切都会因上述错误而崩溃。可能与这个未回答的问题有关?
这是我的标头声明(为了清楚起见,省略了 iVar 和属性:
@interface ArticleTileViewController : UIViewController<UIGestureRecognizerDelegate> {
}
-(void)handleTap:(UITapGestureRecognizer *)sender;
I have a UITableView with custom cells. Inside each cell is 2 views. Each view has a UIGestureRecognizer attached to handle tap events. When the view is tapped, I send a message to a UINavigationController to push a detail view. This scenario works fine until I actually scroll the table. After the table is scrolled, the app crashes when the user taps on one of the views inside of a cell. For example, I can load the app, click on a view in the 2nd cell, and get the detail view to be pushed onto the screen properly. From there, I navigate back to the table, scroll to the bottom, back to the top, and tap the same view. From there, the app crashes with an unrecognized selector error. Here is my setup for the gesture (in viewDidLoad):
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(handleTap:)];
[self.view addGestureRecognizer:recognizer];
recognizer.delegate = self;
[recognizer release];
And here is the method that is invoked:
-(void)handleTap:(UITapGestureRecognizer *)sender{
NSLog(@"Handling tap on ArticleTileViewController");
ArticleViewController *vc = [[ArticleViewController alloc] initWithArticleData:self.articleDataArray];
PROJECTAppDelegate *appDelegate = (PROJECTAppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate.navController pushViewController:vc animated:YES];
}[appDelegate.navController pushViewController:vc animated:YES];
}
Finally, here is the stack trace I get in the console:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType handleTap]: unrecognized selector sent to instance 0x607ba30'
*** Call stack at first throw:
(
0 CoreFoundation 0x02839b99 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0298940e objc_exception_throw + 47
2 CoreFoundation 0x0283b6ab -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x027ab2b6 ___forwarding___ + 966
4 CoreFoundation 0x027aae72 _CF_forwarding_prep_0 + 50
5 UIKit 0x0057f060 -[UIGestureRecognizer _updateGestureWithEvent:] + 727
6 UIKit 0x0057b8bf -[UIGestureRecognizer _delayedUpdateGesture] + 47
7 UIKit 0x00580152 _UIGestureRecognizerUpdateObserver + 637
8 UIKit 0x00581464 _UIGestureRecognizerUpdateGesturesFromSendEvent + 51
9 UIKit 0x0032a844 -[UIWindow _sendGesturesForEvent:] + 1292
10 UIKit 0x003263bf -[UIWindow sendEvent:] + 105
11 UIKit 0x00309cb4 -[UIApplication sendEvent:] + 447
12 UIKit 0x0030e9bf _UIApplicationHandleEvent + 7672
13 GraphicsServices 0x02f07822 PurpleEventCallback + 1550
14 CoreFoundation 0x0281aff4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
15 CoreFoundation 0x0277b807 __CFRunLoopDoSource1 + 215
16 CoreFoundation 0x02778a93 __CFRunLoopRun + 979
17 CoreFoundation 0x02778350 CFRunLoopRunSpecific + 208
18 CoreFoundation 0x02778271 CFRunLoopRunInMode + 97
19 GraphicsServices 0x02f0600c GSEventRunModal + 217
20 GraphicsServices 0x02f060d1 GSEventRun + 115
21 UIKit 0x00312af2 UIApplicationMain + 1160
22 PROJECT 0x00002459 main + 121
23 PROJECT 0x000023d5 start + 53
24 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException
'
EDIT: After testing with this for a while, I've determined that only the views that are visible on the screen at the time will fire the event. Everything else crashes with the above error. Possibly related to this unanswered question?
Here is my header declaration (iVars and properties omitted for clarity:
@interface ArticleTileViewController : UIViewController<UIGestureRecognizerDelegate> {
}
-(void)handleTap:(UITapGestureRecognizer *)sender;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
基本上,这个问题意味着您正在向一个根本无法识别该消息的对象发送消息,即缺少该方法。
您的选择器创建不正确,它应该是:
和
--UPDATE--
我很抱歉询问,但您确定“self”实际上具有方法
handleTap:
吗?Basically this problems means that you are sending a message to an object that does not recognize the message at all, ie the method is missing.
Your selector creation is incorrect it should be:
and
--UPDATE--
I apologize for asking, but are you sure that 'self' actually has the method
handleTap:
?我知道我做错了什么。在我的初始化代码(来自另一个 ViewController)中,我在将 ArticleTileViewController 添加到 UITableViewCell 后释放了它们。这导致向不再位于内存中的对象发送消息。
愚蠢的程序员错误!!
I figured out what I was doing wrong. In my initialization code (from another ViewController), I was releasing the ArticleTileViewControllers after I added them to the UITableViewCell. This was causing an object to be messaged that was no longer in memory.
Stupid programmer mistake!!
如果您不想实现委托方法,则无需将委托设置为 self。
如果您只实现 userTouchedTheView: 方法,也可以工作。
You do not need to set the delegate to self if you do not want to implement the delegate methods.
would also work if you only implement userTouchedTheView: method.