2015-10-11 54 views
0

過去一天我一直在撞牆,或者試圖弄清楚這個問題,所以我希望有人可以幫忙!EXC_BAD_ACCESS在自定義UITableViewCell

我只是想創建一個UITableViewCell的自定義子類,但我的應用程序不斷崩潰在我的自定義TableViewCell的init函數中的EXC_BAD_ACCESS錯誤。我在Xcode的7.01

DiscoverViewController.swift

import UIKit 

class DiscoverViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 

    let networkInterface: GfyNetwork = GfyNetwork() 

    var gfyArray: Array<GfyModel> = [] 
    var tableView: UITableView = UITableView() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 

     self.title = "Discover" 

     let navbar = self.navigationController!.navigationBar 
     navbar.tintColor = UIColor(red:0.32, green:0.28, blue:0.61, alpha:1.0) 

     networkInterface.getTrendingGfys("", completionHandler: printGfys) 

     tableView.frame   = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height); 
     tableView.delegate  = self 
     tableView.dataSource = self 
     tableView.separatorStyle = .None 
     tableView.rowHeight  = 260 
     tableView.contentInset = UIEdgeInsetsMake(10, 0, 10, 0) 
     tableView.registerClass(GfyTableViewCell.self, forCellReuseIdentifier: "gfycell") 

     self.view.addSubview(tableView) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func printGfys(gfyJSON: Array<GfyModel>) -> Array<GfyModel> { 
     // Array of fetched gfys 
     self.gfyArray = gfyJSON 
     // Update Tableview 
     dispatch_async(dispatch_get_main_queue()) { 
      self.tableView.reloadData() 
     } 
     return gfyJSON 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return self.gfyArray.count 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     guard let cell = tableView.dequeueReusableCellWithIdentifier("gfycell", forIndexPath: indexPath) as? GfyTableViewCell else { fatalError("unexpected cell dequeued from tableView") } 
     cell.gfy = self.gfyArray[indexPath.row] 

     return cell 
    } 

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
     print("You selected cell #\(indexPath.row)!") 
    } 
} 

GfyTableViewCell.swift

import UIKit 

class GfyTableViewCell: UITableViewCell { 

    let padding: CGFloat = 5 

    var gfy: GfyModel! 

    var bgView: UIView! 
    var imageURL: UIImageView! 
    var title: UILabel! 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     // Initialization code 
    } 

    override func setSelected(selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 

     // Configure the view for the selected state 
    } 

    required init(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    convenience override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 
     self.init(style: style, reuseIdentifier: reuseIdentifier) // Error happens here 

     backgroundColor = UIColor.whiteColor() 
     selectionStyle = .None 

     bgView.frame = CGRectMake(8, 0, contentView.frame.width-16, 250) 
     bgView.layer.cornerRadius = 3 
     bgView.layer.borderColor = UIColor(red:0, green:0, blue:0, alpha:0.4).CGColor 
     bgView.layer.borderWidth = 0.5 
     bgView.clipsToBounds = true 
     bgView.backgroundColor = UIColor.whiteColor() 

     title.frame = CGRectMake(10, 210, bgView.frame.width-100, 10) 
     title.text = gfy.title 
     title.font = UIFont.systemFontOfSize(10) 

     imageURL.frame = CGRectMake(0, 0, bgView.frame.width, 200) 
     if let url = NSURL(string: gfy.thumbUrl) { 
      if let data = NSData(contentsOfURL: url){ 
       imageURL.contentMode = UIViewContentMode.ScaleAspectFill 
       imageURL.image = UIImage(data: data) 
      } 
     } 

     contentView.addSubview(bgView) 
     bgView.addSubview(imageURL) 
    } 

    override func prepareForReuse() { 
     super.prepareForReuse() 
    } 

    override func layoutSubviews() { 
     super.layoutSubviews() 
    } 

} 

任何幫助將非常感激。使用標準UITableViewCells當應用程序的工作原理,但只要我嘗試添加自定義tableviewcells,它炸燬:(

編輯:

這是我的籌碼是什麼樣子我敢肯定我。在做錯事在我重寫init()函數GfyTableViewCell.swift,但我不知道那是什麼:

call stack

回答

3

這裏的問題是,在init方法調用本身更換以下。 line:

self.init(style: style, reuseIdentifier: reuseIdentifier) 

有:

super.init(style: style, reuseIdentifier: reuseIdentifier) 

如果你調用它自己內部的方法將遞歸調用自身直到程序崩潰,最終因爲一個堆棧溢出或耗盡內存。這並不明顯,爲什麼這與EXC_BAD_ACCESS崩潰,但這可能導致一個實例未能實際分配。

+0

我真的認爲這是事實,但是當我將其更改爲super.init()的Xcode給了我下面的編譯器錯誤: 'GfyTableViewCell.swift:37:15:便利初始化爲「GfyTableViewCell」必須委託(使用'self.init')而不是鏈接到超類初始化器(使用'super.init')' – Sang

+0

實際上,從頭開始。問題是我重寫了便利初始值設定項。只要調用'override init(...)'而不是'convenience override init(...)',就可以毫無問題地使用'super.init(...)'。謝謝!將這個答案標記爲已接受。 – Sang

+1

太棒了。這就說得通了。我以爲你也可能會收到警告。在Swift中,每個初始化器都可能是一個方便的或者是一個指定的初始化器。指定的初始化程序應調用超類的初始化程序(如果存在)並完全初始化一個對象。一個方便的初始化器應該調用'self'上的另一個初始化器。所以,正如你所說,除了改變這一行之外,你還需要更改該初始化程序的聲明以表明你符合那個標準。 –

0

哇,正如我所料,這是我的一個簡單的錯誤。

,不再撥打電話:

convenience override init(style: UITableViewCellStyle, reuseIdentifier: String?) { ... } 

好像我需要溝convenience,只是稱:

override init(style: UITableViewCellStyle, reuseIdentifier: String?) { ... } 

然後,我可以做安東尼上面貼和呼叫super.init(style: style, reuseIdentifier: reuseIdentifier)沒有任何錯誤。

0

修復:對於Xcode 7.1.1中的自定義TableviewCell。

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    let cellT = cell as! CustomTableViewCellName 
    //enter code here 
}