2014-06-10 6 views
9

Ich bin durch und lernen Swift durch die Portierung einer bestehenden Anwendung. Ich setze einen Delegierten fest und kann nicht herausfinden, was das Problem ist.Swift Set Delegate an sich selbst gibt EXC_BAD_ACCESS

Ich habe eine Klasse, die 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) 
    } 

} 

Dann in der Viewcontroller erstreckt, ist definiert als

class SettingsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwitchCellDelegate { 

und innerhalb des Verfahrens

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 er trifft die aktuelle Einstellung des Delegierten die App stürzt mit

EXC_BAD_ACCESS (code = 1, Adresse = 0xfffffffffffffff8)

Ich sollte auch beachten, Wenn ich den delegate-Wert nicht setze, wenn delegate? .switchChanged (self, state: swtSelector.on) ausgelöst wird, verursacht dies auch einen EXC_BAD_ACCESS-Fehler, aber gemäß dem doco für Delegaten sollte dies ordnungsgemäß fehlschlagen, wenn delegate auf nichts gesetzt ist.

===========================

Ich habe mit einem Grundentwurf vereinfacht nach unten 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 einzige Tabelle View-Controller-Szene mit Klasse von TestTableViewController. Die Tabellensicht ist dynamisch mit einer einzelnen Zelle vom Typ TestCell. Diese Zelle enthält ein Label und einen Switch, die an die IBOutlets der TestCell-Klasse gebunden sind. Die switchChanged-Funktion ist an das Ereignis "value changed" auf dem Switch gebunden.

Derselbe Fehler EXC_BAD_ACCESS wird ausgelöst.

+0

Ich bin nicht in der Lage, dies zu reproduzieren. Kannst du mehr Code posten? Haben Sie versucht, den Debugger zu verwenden, um die NSLog-Zeile anzuhalten und zu sehen, was die Variablen sind (wie 'storeCredentialsCell',' self' usw.)? – jtbandes

+0

Versuchen Sie, den Delegat 'var delegate zu initialisieren: SwitchCellDelegate?nil' = – Dash

+0

Dies ist, was die NSLog Linie produziert: 2014.06.10 14: 31: 59,310 SmartDelivery [316: 60b] Einstellung Delegierter <_TtC13CantaraClient22SettingsViewController: 0x13fd05ec0> für <_TtC13CantaraClient10SwitchCell: 0x13fd1f4f0; baseClass = UITableViewCell; Rahmen = (0 0; 540 44); Schicht = > – Moth

Antwort

21

Zur Zeit haben Sie mit @objc markieren Sie Ihre Protokolle explizit auf, wenn die Delegierten ein Objekt einer objektiv-sein sollte C-Klasse (wie der UITableViewController):

@objc protocol SwiftProtocol 

Dies ermöglicht Interoperabilität mit Objective-C

+4

Mann, swift ist ein Durcheinander! – Chet

+2

Es könnte sein, dass Swift kein Durcheinander ist, sondern eine Beta. Es scheint, dass dies ein Fehler ist, der (wie wir hoffen) behoben wird. Gerade jetzt (Xcode 6 Beta 5) funktionieren starke Delegierte gut, aber schwache Delegierte funktionieren immer noch nicht. – George

5

Und nun die Lösung ....

@objc protocol SwitchCellDelegate 

statt

protocol SwitchCellDelegate 
Verwandte Themen