Incorrect nullability specifier in UITableViewRowAction

Originator:B.H.Carpenter
Number:rdar://31820453 Date Originated:25-Apr-2017
Status:Open Resolved:
Product:UIKit Product Version:
Classification:Crash Reproducible:Rarely
 
Summary:
The `handler` argument to +[UITableViewRowAction rowActionWithStyle:title:handler:] accepts a nonnil `action` and `indexPath`, but in some situations it is invoked with a nil `action`. Aside from unintended behavior, this can cause a crash if the UITableViewRowAction is instantiated from Swift, since the `handler` is a Swift closure that expects a non-optional `indexPath`.

A quick look through -[UITableView _actionButton:pushedInCell:] reveals that the result of -[UITableView indexPathForCell:] (which may be nil) is passed directly to the handler without validation.

Steps to Reproduce:
Unsure what exactly causes indexPathForCell: to return nil for a cell that is handling a UITableViewRowAction, but it's possible that the table view may reloadData before the tap gesture recognized?

I've attached a stack trace from a recent crash in the Twitter for iOS app.

Expected Results:
Either maintain the existing behavior and annotate UITableViewRowAction to match the behavior, or do not invoke the UITableViewRowAction handler if the indexPath is nil.

Actual Results:
UITableViewRowAction's handler is passed a nil argument, causing a crash.

Version:
iOS 10.3.1 (14E304)

Notes:
 Also observed on:
iPhone 4s/iOS 9.3.5 (13G36)
iPhone 5s/iOS 10.2.0 (14C92)
iPhone 7/iOS 10.3.1 (14E304)
iPhone 6/iOS 10.2.1 (14D27)
and many other configurations.

Twitter for iOS sees about 100 of these crashes per day.

Configuration:
iPhone 5s

Attachments:
'stacktrace.txt' was successfully uploaded.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!