Custom UITableViewCell delegate pattern in Swift

2019-01-27 06:06发布

I have a weird problem in a Swift + Objective-C problem.

I'm implementing a UITableView and a custom cell with a delegate in swift, but as soon as my UITableViewController assign my cell delegate to self, it crash both my app and Xcode. Yeah each time I crash my app, Xcode crash too, no matter what, but this is another problem.

Here is a part of my cell

enum NewsCellActionType: Int {  
    case Vote = 0
    case Comments
    case Time
}

protocol NewsCellDelegate {
    func newsCellDidSelectButton(cell: NewsCell, actionType: NewsCellActionType)
}

class NewsCell: UITableViewCell {



    var cellDelegate: NewsCellDelegate?

 func selectedAction(action: NewsCellActionType) {
        self.cellDelegate?.newsCellDidSelectButton(self, actionType: action)
    }
}

And here is where I set the delegate in my UIViewController

 override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
        var cell = tableView.dequeueReusableCellWithIdentifier(NewsCellsId) as NewsCell
        if cell == nil {
            cell = NewsCell(style: UITableViewCellStyle.Default, reuseIdentifier: NewsCellsId)
        }
        cell.post = self.posts[indexPath.row] as HNPost
        cell.cellDelegate = self
        return cell

    }

It crash at the line cell.cellDelegate = self, I have no idea why. Is it a bug in the current DP, or am I doing it wrong?

I tried to use weak on my delegate var + the @objc tag on the protocol, but as I use a pure Swift enum I can't do that. But do I need it?

Thanks!

3条回答
啃猪蹄的小仙女
2楼-- · 2019-01-27 06:16

protocol NewsCellDelegate:class { func newsCellDidSelectButton(cell: NewsCell, actionType: NewsCellActionType) }

you're missing a "class"

查看更多
聊天终结者
3楼-- · 2019-01-27 06:38

I needed two changes to make your code work

1. replaced as with as? after tableView.dequeueReusableCellWithIdentifier

(see UITableView in Swift for more details)

The first change not needed because the cell can't be nil (storyboard ensures it). I have built the code wrong.

2. Added @class_protocol to the NewsCellDelegate

@class_protocol protocol NewsCellDelegate {

I am not really sure why the app crashes without it and I think it's a bug. However, @class_protocol should be used anyway because we should declare the cellDelegate as weak and without @class_protocol we can't do it.

weak var cellDelegate: NewsCellDelegate?

Unfortunately, adding weak makes the app crash when the delegate is used.

There is an enourmous number of memory leaks in your code, starting with the library, which is written with ARC but it is set as MRC.

Your closures in NewsCell are capturing self, creating retain cycles (and subsequently leaked cells).

I wasn't able to find the reason of the crash but I am pretty sure it's a bug in the compiler/runtime because it is not only crashing the app, but also Xcode and 3 times it even crashed my system.

查看更多
别忘想泡老子
4楼-- · 2019-01-27 06:41

Here I posted the answer.

Currently you have to explicitly mark your protocols with @objc if the delegate should be an Object of a Objective-C class (Like the UITableViewController):

@objc protocol SwiftProtocol

This will enable interoperating with Objective-C

查看更多
登录 后发表回答