KexAri KexAri - 28 days ago 8
Swift Question

Use of closure passed into a function causes a malloc crash

I have a custom UIView controller that I init like so:

inputPhoneNumberView.frame = CGRect(x: 0, y: 0, width: 286, height: 73)
let alert = SAAlertView(title: "Enter Your Phone Number", message: "Enter or update your phone number and we will send you a verification code via SMS.", customView: inputPhoneNumberView)
alert.addAction("Confirm", style: .default, dismissAfterAction: false, hasLoadingIndicator: true) { () -> Void in
print("Hello!") //Testing code
}
alert.addAction(NSLocalizedString("cancel", comment: ""), style: .cancel, actionBlock: nil)
present(alert, animated: true, completion: nil)


Actions can be added to the view controller that are associated to UIButtons inside it. e.g.
alert.addAction(NSLocalizedString("cancel", comment: ""), style: .cancel, actionBlock: nil


An action is a struct defined as so:

struct Action {
var title: String
var style: ActionStyle
var actionBlock: (() -> Void)?
var dismissAfterAction: Bool
var hasLoadingIndicator: Bool
}


The code block in an action is handled in this method:

fileprivate dynamic func doAction(_ sender: CustomButton) {

// Make sure the action should be allowed for default only.

let action = actions[sender.tag]

guard sender.tag >= 0 && sender.tag < actions.count else {
print("No action at that index.", logType: .Error)
return
}

if let block = action.actionBlock {
if action.dismissAfterAction {
dismiss(animated: true, completion: {
block()
})
} else {

block() // The point the crash occurs!
}
} else {
dismiss(animated: true, completion: nil)
}
}


There is an option when creating an action to
dismissAfterAction
i.e. auto dismiss the view controller then perform the code block. However if
dismissAfterAction
is
false
the app will crash with a
malloc error
. It doesn't always crash but if I repeatedly tap the button associated with that action it will eventually. Not sure what's going on here. Has anyone come across anything like this before? Seems to be a problem with the code block.

Answer

I've had likely issue, some time ago. As a fix you can change your code in this way:

        //we already checked action block, so 
        action.actionBlock!()
        //block()  The point the crash occurs!
Comments