我正在通过移植现有应用程序来学习
Swift.我坚持设置一个代表,不能解决问题.
我有一个类可以扩展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)
我还应该注意,如果在委托?.switchChanged(self,state:swtSelector.on)触发时不设置委托值也会导致EXC_BAD_ACCESS错误,但根据代理的doco,如果委托不是设置任何东西
===========================
我简化了一个基本的项目来复制问题.
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!") }
TestCell.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: reuseIdentifier) } @IBAction func switchChanged(sender: UISwitch){ delegate?.eventFired(self) } }
然后我创建了一个具有TestTableViewController类的表视图控制器场景.表视图是动态的,具有TestCell类型的单个单元格.该单元格包含一个标签和一个与TestCell类的IBOutlets绑定的开关. switchChanged函数绑定到交换机上的值更改事件.
相同的EXC_BAD_ACCESS错误被抛出.
目前,如果委托应该是Objective-C类的对象(如UITableViewController),则必须使用@objc显式标记协议:
@objc protocol SwiftProtocol
这将能够与Objective-C进行互操作