【问题标题】:Error message: [__NSCFType _canScrollX]: unrecognized selector错误消息:[__NSCFType _canScrollX]:无法识别的选择器
【发布时间】:2013-11-19 21:15:19
【问题描述】:

当我从 UIWebView 滑动到 UIScrollView 时,我通常(但并非总是)更新该应用程序会崩溃。有时它会给出标题中显示的错误。大多数时候没有错误信息。奇怪的是,如果我使用按钮移动到下一个屏幕,它不会崩溃。按钮和滑动手势识别器调用相同的处理程序。

我在运行 iOS 5.1.1 的第一代 iPad 上遇到了崩溃,据我所知,当我在 6 月份提交它时,它在任何当前版本的 iOS 5 上都能正常工作。我从应用商店下载了该应用的副本,它还在运行 iOS 5.1.1 的 iPad 上崩溃。

我的解决方法是在 6.0 以下的版本上禁用滑动。

if ( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0") ) {
            UISwipeGestureRecognizer *swipeNext;
            swipeNext = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeNext)];
            [swipeNext setDirection:(UISwipeGestureRecognizerDirectionLeft)];
            [self.view addGestureRecognizer:swipeNext]; 
}

当我在 iOS6 和 iOS7 中测试时,它运行良好。我没有设置_canScrollX。事实上,我什至在文档中都找不到那个方法[编辑:它可能是一个属性,而不是一个方法]。我只在滚动视图上设置了两个属性。

CGFloat quizHeight = ceilf(.9f * _parentView.bounds.size.height - verticalOffset);
        CGRect quizBounds = CGRectMake(0, verticalOffset, _parentView.bounds.size.width, quizHeight );
        _quizView = [[UIScrollView alloc] initWithFrame:quizBounds];
        _quizView.delaysContentTouches = YES;
        _quizView.maximumZoomScale = 1.0f; // Helps with swiping

我认为这不是内存问题,因为它通常会在第一个屏幕上崩溃。我检查了我的代码是否有 iOS5 不支持的方法,并且没有。但即使有,我认为应用程序会一直崩溃,而不是偶尔崩溃,并且它会给我一条关于导致问题的选择器的错误消息。

所以我很难过。有什么想法吗?

[Edit{ 我尝试在启用僵尸的情况下运行并且没有任何问题。当我使用屏幕上的按钮从一个屏幕移动到另一个屏幕时,实时字节会波动,但会返回到 2.4MB 左右。如果我滑动,我会崩溃,并且在 Instruments 中没有显示原因。

在屏幕之间成功移动与崩溃之间的唯一区别是滑动手势。屏幕上的按钮和滑动手势识别器都调用相同的方法。

这是崩溃日志。

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                 0x336f0f78 objc_msgSend + 16
1   UIKit                           0x332f50e2 -[UIScrollViewPanGestureRecognizer _centroidMovedTo:atTime:] + 298
2   UIKit                           0x332f4f50 -[UIPanGestureRecognizer touchesMoved:withEvent:] + 308
3   UIKit                           0x332f4d52 -[UIScrollViewPanGestureRecognizer touchesMoved:withEvent:] + 70
4   UIKit                           0x331ec484 -[UIWindow _sendGesturesForEvent:] + 356
5   UIKit                           0x331ec1ee -[UIWindow sendEvent:] + 82
6   UIKit                           0x331d268e -[UIApplication sendEvent:] + 350
7   UIKit                           0x331d1f34 _UIApplicationHandleEvent + 5820
8   GraphicsServices                0x337c4224 PurpleEventCallback + 876
9   CoreFoundation                  0x35aa651c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32
10  CoreFoundation                  0x35aa64be __CFRunLoopDoSource1 + 134
11  CoreFoundation                  0x35aa530c __CFRunLoopRun + 1364
12  CoreFoundation                  0x35a2849e CFRunLoopRunSpecific + 294
13  CoreFoundation                  0x35a28366 CFRunLoopRunInMode + 98
14  GraphicsServices                0x337c3432 GSEventRunModal + 130
15  UIKit                           0x33200cce UIApplicationMain + 1074
16  Comprehension                   0x000623d4 main (main.m:14)
17  Comprehension                   0x00062388 start + 32

【问题讨论】:

  • 你能发布原始代码,而不仅仅是解决方法吗?
  • 原代码一样,把条件去掉就好了。
  • 如果你得到“无法识别的选择器”并且类名是 Cocoa 内部的东西,就像你所拥有的一样,这通常是由于对象被过早释放。在启用僵尸的情况下构建/运行,看看会发生什么。

标签: xcode ios5


【解决方案1】:

这似乎是 iOS5 和旧 iPad 上的时间问题。

我将 iOS5 的滑动手势识别器更改为

swipeNext = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeNextAfterDelay)];

并添加了延迟滑动后运行的代码的处理程序。

- (void)handleSwipeNextAfterDelay {
        [self performSelector:@selector(handleSwipeNext) withObject:nil afterDelay:0.2];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多