pickerview上的随机崩溃didSelect:__ cffrloloop_is_calling_out_to_a_source1_perform1_function
我收到了以下崩溃报告,但我不明白这个问题.Line 487指向检查委托中的pickerView是否是特定变量。
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:
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) }
我怀疑问题出在对==
的调用中。
if pickerView == assignedTo
这不是你的意思。 这会强制调用==
函数并尝试评估这两个对象之间的相等性。 如果其中一个是nil
将崩溃。
pickerView
永远不应该是nil
,但是我遇到过UIKit发送nil
参数的情况,这些参数永远不应该是nil
。 (如果在后台线程上有任何对UIKit方法的调用,尤其会发生这种情况。请注意不要这样做,但也可能因UIKit错误而发生。)
如果视图未加载,则assignedTo
可以为nil
。 从理论上讲,在这种情况下你永远不应该接受这个调用,但同样,在出现bug时也是可能的,最常见的原因是从主线程调用UIKit方法(任何UIKit方法;它并不总是与这个特殊的选择器视图),但UIKit有时会有自己的错误。
无论如何,你并不是说“pickerView 等于 assignedTo”。 你的意思是“pickerView 与 assignedTo 完全相同 。” 那是===
:
if pickerView === assignedTo
===
做一个指针比较,所以即使面对一个无效的nil
也是安全的。
请记住,这几乎肯定与竞争条件有关。 在调试器中运行它时不容易重现的事实并不意味着什么。 它可能会在10k次尝试中发生一次,仅在Release中,仅在iPhone 6上发生。这就是竞争条件的本质。