我的代码中有一个问题,我无法弄清楚。当我运行我的应用程序时,有时会加载我的单元格,有时会立即崩溃。我相信我的问题出在我的cellForRowInIndexPath
。
我的错误在cellForRowInIndexPath
:
cellDrawer.insertDescriptionLabel(cell, text: offer.title)
这是我的错误:
Thread 1: EXC_BAD_ACCESS(code=1,address=0x0)
这是我的代码:
import UIKit
class ProdutsViewController: UIViewController, UITableViewDelegate,UITableViewDataSource,UISearchResultsUpdating{
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var tableViewFooter: MyFooter!
var searchResults:[Offer] = []
var resultSearchController = UISearchController()
var loading = false
lazy var offers:[Offer]? = {
print("lazy of offers\n")
var restConnection = RestFulConnection()
restConnection.fetchDataFromServer()
return DataBaseChecker.getDataFromDatabase()
}()
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad\n")
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.searchResultsUpdater = self
controller.dimsBackgroundDuringPresentation = false
controller.searchBar.sizeToFit()
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
// Reload the table
self.tableView.reloadData()
self.tableViewFooter.hidden = true
loadSegment()
}
class MyDataProvider {
class func getInstance() -> MyDataProvider {
print("getInstance of MyDataProvider\n")
return MyDataProvider() //return a new instance since class vars not supported yet
}
func requestData(listener:([Offer]) -> ()) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
//simulate delay
sleep(1)
print("requestData of MyDataProvider\n")
//generate items
var restConnection = RestFulConnection()
restConnection.fetchDataFromServer()
var arr = DataBaseChecker.getDataFromDatabase()
//call listener in main thread
dispatch_async(dispatch_get_main_queue()) {
listener(arr)
}
}
}
}
func scrollViewDidScroll(scrollView: UIScrollView) {
print("scrollViewDidScroll\n")
let currentOffset = scrollView.contentOffset.y
let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height
if (maximumOffset - currentOffset) <= 40 {
print("IF of scrollViewDidScroll\n")
loadSegment()
}
}
func loadSegment() {
print("loadSegment\n")
if (!self.loading) {
self.setLoadingState(true)
print("IF of loadSegment\n")
MyDataProvider.getInstance().requestData(
{(offers:[Offer]) -> () in
print("block of requestData on method loadSegment\n")
for offer:Offer in offers {
print("for of loadSegment\n")
if(DataBaseChecker.isItNew(offer)){
self.offers?.append(offer)
}
}
self.tableView.reloadData()
self.setLoadingState(false)
})
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
print("didReceiveMemoryWarning\n")
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = self.tableView.dequeueReusableCellWithIdentifier("Cell",forIndexPath: indexPath) as! UITableViewCell
print("CellForRowAtIndexPath\n")
// var offer:Offer?
// if (self.resultSearchController.active) {
// offer = searchResults[indexPath.row]
// } else {
// offer = offers?[indexPath.row]
// }
if(offers != nil){
var offer:Offer = offers![indexPath.row]
print("IF of offers not nil, offers = \(offer.title)\n")
var cellDrawer = CellDrawer()
if (cell.viewWithTag(1) == nil){
cellDrawer.createWhiteContentInCell(cell)
}
cellDrawer.insertImageInCell(offer.images, cell: cell)
cellDrawer.insertBlackContentInCell(cell)
cellDrawer.insertDescriptionLabel(cell, text: offer.title)
cellDrawer.insertLocalLabel(cell, text: "String Sample")
cellDrawer.insertOldPriceLabel(cell, number: offer.oldPrice)
//cellDrawer.insertFromPriceLabel(cell, text: "a partir de")
cellDrawer.insertNewPriceLabel(cell,number:offer.newPrice)
}
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("NumberOfRowsInSection\n")
if(offers != nil){
print("IF offers not nil of NumberOfRowsInSection\n")
if (self.resultSearchController.active) {
print("IF2 of NumberOfRowsInSection\n")
return searchResults.count
} else {
print("ELSE of NumberOfRowsInSection, offers count = \(offers!.count)\n")
return offers!.count
}
}
return 0
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
print("numberOfSectionsInTableView\n")
if(offers != nil && offers!.count >= 1){
print("if of numberOfSectionsInTableView\n")
return 1
}
return 0
}
func setLoadingState(loading:Bool) {
print("setLoadingState\n")
self.loading = loading
self.tableViewFooter.hidden = !loading
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
print("heightForRowAtIndexPath\n")
return 235
}
func updateSearchResultsForSearchController(searchController: UISearchController)
{
print("updateSearchResultsForSearchController\n")
if(offers != nil){
print("if of updateSearchResultsForSearchController")
searchResults.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "title CONTAINS[c] %@", searchController.searchBar.text)
let array = NSArray(array: offers!)
array.filteredArrayUsingPredicate(searchPredicate)
self.searchResults = array as! [Offer]
self.tableView.reloadData()
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
print("prepareForSegue\n")
if segue.identifier == "detailsSegue" {
print("IF of prepareForSegue\n")
let DetailTVC = segue.destinationViewController as! DetailsTVC
if sender as! UITableView == self.resultSearchController.active {
print("IF2 of prepareForSegue\n")
let indexPath = self.tableView.indexPathForSelectedRow()!
let offer = self.searchResults[indexPath.row]
DetailTVC.offer = offer
} else {
print("Else of prepareForSegue\n")
let indexPath = self.tableView.indexPathForSelectedRow()!
let offer = self.offers![indexPath.row]
DetailTVC.offer = offer
}
}
}
}
希望有人可以提供帮助。
答案 0 :(得分:1)
如果offer.title不是nil,那么cellDrawer可能会在不再有效的单元格上执行某些操作。
设置断点并使用调试器中的po(print object)检查offer.title属性。
当抽屉试图加载标题时,也可能是正在更新商品数组的竞争条件。
答案 1 :(得分:0)
看起来您没有为重用标识符注册类。在viewDidLoad函数中应该有:
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
答案 2 :(得分:0)
在这种情况下,我认为报价本身是零,当你尝试获得title属性/ ivar时,你会遇到崩溃。
答案 3 :(得分:0)