本文介绍了pickerview didSelect上的随机崩溃:__cfrunloop_is_calling_out_to_a_source1_perform1_function的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经收到以下崩溃报告,但我不理解该问题.第487行指向检查委托中的pickerView是否为特定变量.

I have received the following crash report but I do not understand the issue.Line 487 points to a check if the pickerView in the delegate is a particular variable.

Crashed: com.apple.main-thread
0  App                    0x1001c5208 specialized NewCorrectiveVC.pickerView(UIPickerView, didSelectRow : Int, inComponent : Int) -> () (NewCorrectiveVC.swift:487)
1  App                    0x1001c2028 @objc NewCorrectiveVC.pickerView(UIPickerView, didSelectRow : Int, inComponent : Int) -> () (NewCorrectiveVC.swift)
2  UIKit                  0x197a83154 -[UIPickerView _sendSelectionChangedForComponent:notify:] + 116
3  UIKit                  0x197a8338c -[UIPickerView _sendSelectionChangedFromTable:notify:] + 344
4  UIKit                  0x197fb0424 -[UIPickerTableView _scrollingFinished] + 188
5  UIKit                  0x197fb05fc -[UIPickerTableView scrollViewDidEndDecelerating:] + 28
6  UIKit                  0x197b216ac -[UIScrollView(UIScrollViewInternal) _scrollViewDidEndDeceleratingForDelegate] + 132
7  UIKit                  0x1979b6db0 -[UIScrollView(UIScrollViewInternal) _stopScrollDecelerationNotify:] + 332
8  UIKit                  0x1979b68ec -[UIScrollView _smoothScrollWithUpdateTime:] + 2356
9  QuartzCore             0x194bc01bc CA::Display::DisplayLinkItem::dispatch(unsigned long long) + 44
10 QuartzCore             0x194bc0068 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 444
11 IOKit                  0x191c27138 IODispatchCalloutFromCFMessage + 372
12 CoreFoundation         0x19195056c __CFMachPortPerform + 180
13 CoreFoundation         0x191968934 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56
14 CoreFoundation         0x1919680e8 __CFRunLoopDoSource1 + 436
15 CoreFoundation         0x191965bcc __CFRunLoopRun + 1840
16 CoreFoundation         0x191894048 CFRunLoopRunSpecific + 444
17 GraphicsServices       0x19331a198 GSEventRunModal + 180
18 UIKit                  0x1978792fc -[UIApplication _run] + 684
19 UIKit                  0x197874034 UIApplicationMain + 208
20 App                    0x100173d04 main (AppDelegate.swift:22)
21 libdispatch.dylib      0x1908785b8 (Missing)

代码:

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
{
    if pickerView == assignedTo
    {
        if employees.count > 0 {
            selectedEmp =  employees[row].employeeId
        }
    }
    else if pickerView == category \\this is line 487
    {
        if categories.count > 0 {
            selectedCat = categories[row].wocategoryId
        }
    }
}

不确定以下内容是否相关,但我确实有与我的pickerViews链接的观察者:

Not sure if the following is relevant but I do have observers linked to my pickerViews:

let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressed))
assignedTo.addGestureRecognizer(longPressRecognizer)
let catLongPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.catLongPressed))
category.addGestureRecognizer(catLongPressRecognizer)
self.hideKeyboardWhenTappedAround()
self.scroll.keyboardDismissMode = .interactive

仅供参考:

public func hideKeyboardWhenTappedAround() {
    let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
    view.addGestureRecognizer(tap)
}

推荐答案

我怀疑问题出在==的调用中.

I suspect the problem is in the call to ==.

if pickerView == assignedTo

这不是您的意思.这将强制调用==函数,并尝试评估这两个对象之间的相等性.如果其中一个是nil,则会崩溃.

This isn't really what you mean. This forces a call to the == function and tries to evaluate equality between these two objects. If one of them is nil that will crash.

pickerView永远不应为nil,但是我遇到过UIKit发送nil来获取不应为nil的参数的情况. (尤其是在后台线程上有对UIKit方法的任何调用时,就会发生这种情况.请务必谨慎操作,但也可能由于UIKit错误而发生这种情况.)

pickerView should never be nil, but I've encountered cases where UIKit sends nil for parameters that should never be nil. (This especially can happen if there are any calls to UIKit methods on background threads. Be very careful about not doing that, but it can also happen due to UIKit bugs.)

assignedTo可以为nil.从理论上讲,您永远都不会在这种情况下进行此调用,但是再次,有可能存在错误,这同样是最常见的原因,这是由于从主线程上调用了UIKit方法(任何UIKit方法;它不一定总是与这个特定的选择器视图),但UIKit有时有其自身的错误.

assignedTo can be nil if the view hasn't loaded. In theory you should never get this call in that case, but again, it's possible in the presence of bugs, again most commonly due to calling UIKit methods off the main thread (any UIKit methods; it doesn't always have to be related to this particular picker view), but UIKit sometimes has bugs of its own.

在任何情况下,您的意思都不是"pickerView 等于等于assignedTo".您的意思是"pickerView与分配的对象完全相同".那是===:

In any case, you don't mean "is pickerView equal to assignedTo." You mean "is pickerView exactly the same thing as assignedTo." That's ===:

if pickerView === assignedTo

===进行指针比较,因此即使遇到无效的nil也是安全的.

=== does a pointer comparison, so even in the face of an invalid nil it's safe.

请记住,这几乎可以肯定与比赛条件有关.当您在调试器中运行它时,它不容易重现这一事实并不意味着任何事情.可能仅在iPhone 6上进行1万次尝试,仅在Release中发生.这就是比赛条件的本质.

Keep in mind that this is almost certainly related to a race condition. The fact that it doesn't easily reproduce when you run it in the debugger doesn't mean anything. It might happen once in 10k tries, only in Release, exclusively on iPhone 6. That's the nature of race conditions.

这篇关于pickerview didSelect上的随机崩溃:__cfrunloop_is_calling_out_to_a_source1_perform1_function的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-31 10:05