Ein schneller Stellvertreter zu sich selbst gibt EXC_BAD_ACCESS
Ich lerne Swift, indem ich eine vorhandene Anwendung portiere. Ich bin fest entschlossen, einen Delegierten zu bestimmen, und kann das Problem nicht herausfinden.
Ich habe eine Klasse, die UITableViewCell erweitert
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)
}
}
Dann ist im ViewController definiert als
class SettingsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwitchCellDelegate {
und innerhalb der Methode
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
wir haben
case 2:
storeCredentialsCell = tableView.dequeueReusableCellWithIdentifier("StoreCredentialsCell") as? SwitchCell
if(storeCredentialsCell != nil){
...
NSLog("Setting delegate to %@ for %@", self.description, storeCredentialsCell.description)
storeCredentialsCell!.delegate = self
...
}
Die Protokollausgabe ist wie erwartet, aber wenn die tatsächliche Einstellung des Delegaten erreicht wird, stürzt die App ab
EXC_BAD_ACCESS (Code = 1, Adresse = 0xfffffffffffffff8)
Ich sollte auch beachten, dass, wenn ich beim Auslösen von delegate? .SwitchChanged (self, state: swtSelector.on) den Delegatenwert nicht festlege, dies ebenfalls einen EXC_BAD_ACCESS-Fehler verursacht auf irgendetwas setzen.
=========================
Ich habe es auf ein Basisprojekt vereinfacht, um das Problem zu replizieren.
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: String) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
@IBAction func switchChanged(sender: UISwitch){
delegate?.eventFired(self)
}
}
Ich habe dann eine einzelne Table View Controller-Szene mit der Klasse TestTableViewController erstellt. Die Tabellenansicht ist dynamisch mit einer einzelnen Zelle des Typs TestCell. Diese Zelle enthält eine Bezeichnung und einen Schalter, die an die IBOutlets der TestCell-Klasse gebunden sind. Die switchChanged-Funktion ist an das Wertänderungsereignis auf dem Switch gebunden.
Derselbe EXC_BAD_ACCESS-Fehler wird ausgelöst.