Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Swift closure with Objective-C framework

I am using the MCSwipeTableViewCell framework for swipe-able tableviewcells. One of the completion blocks inside a cellForRowAtIndexPath function looks like this:

[cell setSwipeGestureWithView:checkView color:greenColor mode:MCSwipeTableViewCellModeSwitch state:MCSwipeTableViewCellState1 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
      // run some function call
}];

I used a Bridging-Header file to import the framework into my Swift project and am attempting to use that same completion block in Swift. This is what I have:

cell.setSwipeGestureWithView(crossView, color: UIColor.colorFromRGB(RED), mode: MCSwipeTableViewCellMode.Switch, state:MCSwipeTableViewCellState.State1, completionBlock: { (cell: MCSwipeTableViewCell!, state: MCSwipeTableViewCellState!, mode: MCSwipeTableViewCellMode!) -> Void in
    self.runSomeFunction();
});

The problem is, it crashes everytime I run self.runSomeFunction() even though the function call is implemented. The error is

unrecognized selector

sent to instance 0x165c7390
2014-07-07 16:23:14.809 pong[3950:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM runSomeFunction]: unrecognized selector sent to instance 0x165c7390'

I know the completion block works because I can NSLog from it and it displays something, but attempting to access self always results in a crash.

Any ideas? Should I not be trying to access self?

=== Update ===

Mainly what I'm trying to figure out is how to access self within a Swift closure. It keeps throwing a bad access error.

Here is the code that is running

 func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell!
{
    var cell = tableView.dequeueReusableCellWithIdentifier("userCell") as MCSwipeTableViewCell!

    if !cell {
        cell = MCSwipeTableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "userCell")
     }
    cell.setSwipeGestureWithView(crossView, color: UIColor.colorFromRGB(RED), mode: MCSwipeTableViewCellMode.Switch, state:MCSwipeTableViewCellState.State1, completionBlock: { (cell: MCSwipeTableViewCell!, state: MCSwipeTableViewCellState!, mode: MCSwipeTableViewCellMode!) -> Void in
        self.runSomething();
    });
    return cell
}

 func runSomething()
{
    NSLog("hey there");
}
like image 839
Brian Weinreich Avatar asked Oct 31 '22 20:10

Brian Weinreich


1 Answers

You can define a Capture List to use self inside a Closure like this:

cell.setSwipeGestureWithView(crossView, color: UIColor.colorFromRGB(RED), mode: MCSwipeTableViewCellMode.Switch, state:MCSwipeTableViewCellState.State1) {
    [unowned self]
    cell, state, mode in
    self.runSomething()
}

Currently [unowned self] may crash sometimes so for the time being use [weak self] and inside your closure unwrap self like: self!.doSomething().

like image 134
Essan Parto Avatar answered Nov 15 '22 05:11

Essan Parto