2014-06-10 60 views
9

我正在通過移植一個現有的應用程序來學習Swift。我一直在設置一個委託,並且無法弄清楚問題所在。Swift設置代理給自己EXC_BAD_ACCESS

我有延伸的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(代碼= 1,地址= 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: String) { 
     super.init(style: style, reuseIdentifier: reuseIdentifier) 
    } 

    @IBAction func switchChanged(sender: UISwitch){ 
     delegate?.eventFired(self) 
    } 
} 

我然後創建了單個表視圖控制器場景與TestTableViewController的類。表格視圖對於單個TestCell類型的單元格是動態的。該單元格包含一個標籤和一個開關,它們與TestCell類中的IBOutlet綁定。 switchChanged功能綁定到交換機上的值更改事件。

相同的EXC_BAD_ACCESS錯誤被拋出。

+0

我無法重現這一點。你能發佈更多的代碼嗎?您是否嘗試過使用調試器在NSLog行上停止並查看變量是什麼(例如'storeCredentialsCell','self'等)? – jtbandes

+0

嘗試初始化你的委託var delegate:SwitchCellDelegate?= nil' – Dash

+0

這就是NSLog產生的內容:2014-06-10 14:31:59.310 SmartDelivery [316:60b]爲<_TtC13CantaraClient10SwitchCell設置委託給<_TtC13CantaraClient22SettingsViewController:0x13fd05ec0> 0x13fd1f4f0; baseClass = UITableViewCell; frame =(0 0; 540 44);層= > – Moth

回答

21

目前你必須明確地標記你的協議與@objc如果委託應該是Objective-的對象C類(如UITableViewController):

@objc protocol SwiftProtocol 

這將啓用互操作與Objective-C

+4

男人,斯威夫特是一團糟! – Chet

+2

這可能是Swift不是一團糟,而是一個測試版。看來,這是一個(我們希望)將會修復的錯誤。現在(Xcode 6 beta 5),強大的代表工作得很好,但弱代表仍然無法工作。 – George

5

而現在爲解決....

@objc protocol SwitchCellDelegate 

,而不是

protocol SwitchCellDelegate 
相關問題