我正在通过移植现有应用程序来学习 Swift。我坚持设置委托(delegate),无法解决问题所在。
我有一个扩展 UITableViewCell 的类
import UIKit
protocol SwitchCellDelegate{
func switchChanged(switchCell: SwitchCell, state: Bool)
}
class SwitchCell: UITableViewCell {
@IBOutlet var swtSelector: UISwitch
@IBOutlet var lblTitle: UILabel
var delegate: SwitchCellDelegate?
init(style: UITableViewCellStyle, reuseIdentifier: String) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
@IBAction func switchChanged(){
delegate?.switchChanged(self, state: swtSelector.on)
}
}
然后在ViewController中定义为
class SettingsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwitchCellDelegate {
在方法内
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
我们有
case 2:
storeCredentialsCell = tableView.dequeueReusableCellWithIdentifier("StoreCredentialsCell") as? SwitchCell
if(storeCredentialsCell != nil){
...
NSLog("Setting delegate to %@ for %@", self.description, storeCredentialsCell.description)
storeCredentialsCell!.delegate = self
...
}
日志输出符合预期,但当它达到代理的实际设置时,应用程序崩溃
EXC_BAD_ACCESS(code=1, address=0xfffffffffffffff8)
我还应该注意,如果在 delegate?.switchChanged(self, state: swtSelector.on) 触发时我没有设置委托(delegate)值,它也会导致 EXC_BAD_ACCESS 错误,但根据 doco for delegates 如果委托(delegate)未设置任何内容。
===========================
我已简化为一个基本项目来重现该问题。
TestTableViewController.swift
import UIKit
class TestTableViewController: UITableViewController, TestCellDelegate {
init(style: UITableViewStyle) {
super.init(style: style)
}
init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView?) -> Int {
return 1
}
override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
let cell = tableView!.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? TestCell
if(cell != nil){
cell!.delegate = self
cell!.lblTest.text = "Test Successful"
}
return cell
}
func eventFired(sender: TestCell) {
NSLog("Hooray!")
}
测试单元.swift
import UIKit
protocol TestCellDelegate{
func eventFired(sender: TestCell)
}
class TestCell: UITableViewCell {
@IBOutlet var lblTest: UILabel
@IBOutlet var swtTest: UISwitch
var delegate: TestCellDelegate?
init(style: UITableViewCellStyle, reuseIdentifier: String) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
@IBAction func switchChanged(sender: UISwitch){
delegate?.eventFired(self)
}
}
然后我使用 TestTableViewController 类创建了一个 TableView Controller 场景。 TableView 是动态的,带有一个类型为 TestCell 的单元格。该单元格包含一个标签和一个开关,它们绑定(bind)到 TestCell 类的 IBOutlets。 switchChanged 函数绑定(bind)到开关上的值更改事件。
同样的 EXC_BAD_ACCESS 错误被抛出。
最佳答案
目前,如果委托(delegate)应该是 Objective-C 类的对象(如 UITableViewController),您必须使用 @objc
显式标记您的协议(protocol):
@objc protocol SwiftProtocol
这将启用与 Objective-C 的互操作
关于Swift set delegate to self 给出 EXC_BAD_ACCESS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24132738/