iOS – 无法从其dataSource获取单元格

我写了一个swift文件来控制两个用户之间的消息连接。 出于某种原因,该文件在加载时崩溃,并返回此错误:

015-12-18 11:19:07.449 collaboration[4761:357519] *** Assertion failure in -[UITableView _configureCellForDisplay:forIndexPath:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UITableView.m:7962 2015-12-18 11:19:07.453 collaboration[4761:357519] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView (<UITableView: 0x7c9f6400; frame = (16 58; 288 412); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7a7a4170>; layer = <CALayer: 0x7a7a3250>; contentOffset: {0, 0}; contentSize: {288, 44}>) failed to obtain a cell from its dataSource (<collaboration.chatViewController: 0x7a7a0750>)' *** First throw call stack: ( 0 CoreFoundation 0x00304a14 __exceptionPreprocess + 180 1 libobjc.A.dylib 0x02233e02 objc_exception_throw + 50 2 CoreFoundation 0x003048aa +[NSException raise:format:arguments:] + 138 3 Foundation 0x00946d26 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 118 4 UIKit 0x00ede528 -[UITableView _configureCellForDisplay:forIndexPath:] + 228 5 UIKit 0x00eeb3cf -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 877 6 UIKit 0x00eeb4e1 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 90 7 UIKit 0x00ebb948 -[UITableView _updateVisibleCellsNow:isRecursive:] + 3347 8 UIKit 0x00eda0d6 __29-[UITableView layoutSubviews]_block_invoke + 52 9 UIKit 0x00ef519e -[UITableView _performWithCachedTraitCollection:] + 88 10 UIKit 0x00ed9fab -[UITableView layoutSubviews] + 214 11 UIKit 0x00e30008 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 810 12 libobjc.A.dylib 0x02248059 -[NSObject performSelector:withObject:] + 70 13 QuartzCore 0x05bf580a -[CALayer layoutSublayers] + 144 14 QuartzCore 0x05be94ee _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 388 15 QuartzCore 0x05be9352 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26 16 QuartzCore 0x05bdbe8b _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 317 17 QuartzCore 0x05c0fe03 _ZN2CA11Transaction6commitEv + 561 18 QuartzCore 0x05c11674 _ZN2CA11Transaction17flush_transactionEv + 50 19 UIKit 0x00d94dfa _afterCACommitHandler + 197 20 CoreFoundation 0x0021dffe __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30 21 CoreFoundation 0x0021df5e __CFRunLoopDoObservers + 398 22 CoreFoundation 0x002138dc __CFRunLoopRun + 1340 23 CoreFoundation 0x002130e6 CFRunLoopRunSpecific + 470 24 CoreFoundation 0x00212efb CFRunLoopRunInMode + 123 25 GraphicsServices 0x05696664 GSEventRunModal + 192 26 GraphicsServices 0x056964a1 GSEventRun + 104 27 UIKit 0x00d63bfa UIApplicationMain + 160 28 collaboration 0x000b125c main + 140 29 libdyld.dylib 0x02c97a21 start + 1 30 ??? 0x00000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb) 

我不小心删除了这个文件。 幸运的是我有一个备份,所以我能够创build一个新的文件在同一个名字,并将所有的代码粘贴到它。
有问题的代码:

 import UIKit class chatViewController: UIViewController { @IBOutlet weak var tableView: UITableView! var timer = NSTimer() var tableBackgroundInc = 1 let EnigmaMachine = EncryptionMachine() var friendChosen: String! var isConnectedToInternet: Bool! var receivedUsername:String! @IBOutlet weak var testLabel: UILabel! var messageStringRecords = [] var messages: NSMutableArray = NSMutableArray() func sendAlert(subject: String, message: String) { let alertController = UIAlertController(title: subject, message: message, preferredStyle: UIAlertControllerStyle.Alert) alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default,handler: nil)) self.presentViewController(alertController, animated: true, completion: nil) } func tableView(tableView: UITableView, numberOfRowsInSection Section: Int) -> Int { return self.messages.count } /*@IBAction func refreshButton(sender: UIButton) { reloadTable() }*/ @IBOutlet weak var messageTextInput: UITextField! @IBAction func sendButton(sender: UIButton) { let chatPartner = self.friendChosen let username = NSUserDefaults.standardUserDefaults().stringForKey("username")! as String let theMessage = messageTextInput.text! as String let messageTextPreOne = EnigmaMachine.encrypt(theMessage) let messageTextPreTwo = messageTextPreOne.stringByReplacingOccurrencesOfString(" ", withString: "039254space925403") let messageText = self.voidInvalidCharacters(messageTextPreTwo) if messageText != "" { let secretKey = "0000" let myUrl = NSURL(string: "http://www.neverforgottenbbq.com/gfg/sendMessage.php") let request = NSMutableURLRequest(URL: myUrl!) request.HTTPMethod = "POST" let postString = "secretKey=\(secretKey)&username=\(username)&chatPartner=\(chatPartner)&message=\(messageText)" request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding) let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { if let responseData = data { let responseString = NSString(data: responseData, encoding: NSUTF8StringEncoding) if error != nil { print("Error: \(error)") } dispatch_async(dispatch_get_main_queue()) { print("") } } else { print("The connection quit") } } } task.resume() } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! chatTableViewCell //cell.messageLabel?.text = self.messages.objectAtIndex(indexPath.row) as? String let wholeMessage = self.messages.objectAtIndex(indexPath.row) as? String if wholeMessage! as String != "Loading......" && wholeMessage! as String != "No messages" { let splitMessage = wholeMessage!.componentsSeparatedByString("203598123589") let theMessage = splitMessage[0] if EnigmaMachine.decrypt(splitMessage[1]) as String == friendChosen.uppercaseString as String { let completeMessage = friendChosen.uppercaseString + ": " + theMessage cell.messageLabel?.text = completeMessage } else { cell.messageLabel.textAlignment = NSTextAlignment.Right let completeMessage = theMessage cell.messageLabel?.text = completeMessage } } else { cell.messageLabel?.text = wholeMessage! as String } tableView.estimatedRowHeight = requiredHeight(self.messages.objectAtIndex(indexPath.row) as! String) tableView.rowHeight = UITableViewAutomaticDimension cell.layer.cornerRadius = 5 cell.layer.masksToBounds = true return cell } func requiredHeight(text:String) -> CGFloat { let font = UIFont(name: "Georgia", size: 16.0) let label:UILabel = UILabel(frame: CGRectMake(0, 0, 200, CGFloat.max)) label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.ByWordWrapping label.font = font label.text = text label.sizeToFit() return label.frame.height } func reloadTable() { refreshTable() self.messages = [] let chatPartner = NSUserDefaults.standardUserDefaults().stringForKey("usernameToMessageWith")! as String let username = NSUserDefaults.standardUserDefaults().stringForKey("username")! as String let myUrl = NSURL(string: "http://www.neverforgottenbbq.com/gfg/getMessagesForCurrentChat.php") let request = NSMutableURLRequest(URL: myUrl!) request.HTTPMethod = "POST" let postString = "username=\(username)&chatPartner=\(chatPartner)" request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding) let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { if let responseData = data { let responseString = NSString(data: responseData, encoding: NSUTF8StringEncoding) if error != nil { print("Error: \(error)") } dispatch_async(dispatch_get_main_queue()) { self.messageStringRecords = responseString!.componentsSeparatedByString("3292985383") for index in self.messageStringRecords { let indexSplit = index.componentsSeparatedByString("9254203598") if indexSplit.count > 1 { let theMessage = indexSplit[0] let messageId = indexSplit[1] self.updateReadStatus(messageId) let theNewMessage = theMessage self.messages.addObject(self.EnigmaMachine.decrypt(theNewMessage)) self.tableBackgroundInc = 1 self.tableView.reloadData() } } } } else { print("The connection quit") } } } task.resume() self.tableView.estimatedRowHeight = 44.0 self.tableView.rowHeight = UITableViewAutomaticDimension self.tableBackgroundInc = 1 self.tableView.reloadData() } } func updateReadStatus(messageId: String) { let theSecretKey = "0000" let myUrl = NSURL(string: "http://www.neverforgottenbbq.com/gfg/updateReadStatus.php") let request = NSMutableURLRequest(URL: myUrl!) request.HTTPMethod = "POST" let postString = "id=\(messageId)&secretKey=\(theSecretKey)" request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding) let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { if let responseData = data { _ = NSString(data: responseData, encoding: NSUTF8StringEncoding) if error != nil { print("Error: \(error)") } dispatch_async(dispatch_get_main_queue()) { print("") } } else { print("The connection quit") } } } task.resume() } func voidInvalidCharacters(stringToVoid: String) -> String { var returnString = "" var sanitizedArray: [String] = [] let acceptableCharacters = [ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", ".", "_", "~", ":", "/", "?", "#", "[", "]", "@", "!", "$", "'", "(", ")", "*", "+", ",", ";", "=" ] let stringToVoidArray = Array(stringToVoid.characters) for letter in stringToVoidArray { var isAcceptable = false for character in acceptableCharacters { if character as String == String(letter) { isAcceptable = true } } if isAcceptable == true { sanitizedArray.append(String(letter)) } } for letter in sanitizedArray { returnString = returnString + letter } return returnString } func keyboardWillShow(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.view.frame.origin.y -= keyboardSize.height } } func keyboardWillHide(notification: NSNotification) { if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() { self.view.frame.origin.y += keyboardSize.height } } func dismissKeyboard() { self.messageTextInput.resignFirstResponder() } func refreshTable () { let newMessages: NSMutableArray = NSMutableArray() let chatPartner = self.receivedUsername if chatPartner == "" { self.sendAlert("Error", message: "Can not connect to chat partner") } let username = NSUserDefaults.standardUserDefaults().stringForKey("username")! as String let myUrl = NSURL(string: "http://www.neverforgottenbbq.com/gfg/getMessagesForCurrentChat.php") let request = NSMutableURLRequest(URL: myUrl!) request.HTTPMethod = "POST" let postString = "username=\(username)&chatPartner=\(chatPartner)" request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding) let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding) if error != nil { print("Error: \(error)") } dispatch_async(dispatch_get_main_queue()) { if responseString !== "" { self.messageStringRecords = responseString!.componentsSeparatedByString("3292985383") for index in self.messageStringRecords { let indexSplit = index.componentsSeparatedByString("9254203598") let theMessage = indexSplit[0] let theNewMessagePre = theMessage.stringByReplacingOccurrencesOfString("039254space925403", withString: " ") let theNewMessage = theNewMessagePre + "203598123589\(String(indexSplit[3]))" newMessages.addObject(self.EnigmaMachine.decrypt(theNewMessage)) } self.messages = [] for i in newMessages { self.messages.addObject(i) } self.tableBackgroundInc = 1 self.tableView.reloadData() } else { self.messages = [] self.messages.addObject("No messages") self.tableView.reloadData() } } } } task.resume() } override func viewDidLoad() { super.viewDidLoad() NSNotificationCenter.defaultCenter().addObserverForName( UIApplicationUserDidTakeScreenshotNotification, object: nil, queue: NSOperationQueue.mainQueue()) { notification in 2 let chatPartner = self.friendChosen let username = NSUserDefaults.standardUserDefaults().stringForKey("username")! as String let theMessage = "I took a screenshot. I am sorry that I cannot be trusted :(" let messageTextPreOne = self.EnigmaMachine.encrypt(theMessage) let messageTextPreTwo = messageTextPreOne.stringByReplacingOccurrencesOfString(" ", withString: "039254space925403") let messageText = self.voidInvalidCharacters(messageTextPreTwo) if messageText != "" { let secretKey = "00000" let myUrl = NSURL(string: "http://www.neverforgottenbbq.com/gfg/sendMessage.php") let request = NSMutableURLRequest(URL: myUrl!) request.HTTPMethod = "POST" let postString = "secretKey=\(secretKey)&username=\(username)&chatPartner=\(chatPartner)&message=\(messageText)" request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding) let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { _ = NSString(data: data!, encoding: NSUTF8StringEncoding) // lazy responseString: NSString if error != nil { print("Error: \(error)") } dispatch_async(dispatch_get_main_queue()) { //print(responseString) } } } task.resume() } else { self.sendAlert("Error", message: "You cannot send a blank message") } } self.receivedUsername = friendChosen self.tableView.separatorStyle = UITableViewCellSeparatorStyle.None let swipe: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "dismissKeyboard") swipe.direction = UISwipeGestureRecognizerDirection.Down self.view.addGestureRecognizer(swipe) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil) NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil) self.messages.addObject("Loading......") refreshTable() print("this is a test") } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("refreshTable"), userInfo: nil, repeats: true) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) { timer.invalidate() } } 

非常感谢你的帮助,
缺口

我刚刚得到了这一点,并认为它… chatViewController没有标记为实现UITableViewDataSource协议。

这是Swift 3的新行为。

改行:

 class chatViewController: UIViewController { 

至:

 class chatViewController: UIViewController, UITableViewDataSource { 

代码将工作。

该错误实质上是说它无法获得表视图的单元格。 这意味着你从cellForRowAtIndexPath返回nil

但是你有这样一个方法,写成它不能返回nil 。 问题是你的cellForRowAtIndexPath函数被embedded到另一个函数中。 不可能。 确保所有的表视图数据源和委托函数都是类中的顶级函数。

Swift 3.0

你只需要添加UITableViewDelegateUITableViewDataSource

 import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource 

下图仅供参考。

在这里输入图像说明

这种罕见的错误也发生在你没有给你的可重用单元格标识符,但你正在尝试引用它在你的课堂上。

 // Set the cell to be the custom cell let cell : CustomCell! = tableView.dequeueReusableCellWithIdentifier("cell") as? CustomCell 

菜鸟的错误

这是Xcode 8.0的变化

类chatViewController:UIViewController {

将此行更改为此

类chatViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {