我檢索數據處理程序中的新聞提要的數據庫中的帖子,我運行一個PHP腳本和回聲JSON編碼的數據回到我的應用程序,數據被解析並存儲在「post」模型中,在視圖控制器中有一個協議用於下載數據。我的問題是,當我將「post」對象的NSMutableArray傳遞給作爲協議功能的函數「itemsDownloaded」時,我得到臭名昭着的「解包可選值時意外發現零」錯誤。我檢查了所有正在解析的值並存在,我也檢查了數組的數量以確保它具有值。唯一的例外是上線self.delegate.itemsDownloaded(posts)
意外地發現零當展開可選值 - NSMutableArray - 斯威夫特
來處理數據的代碼發生是這樣的:
import Foundation
protocol PostDataHandlerProtocol: class {
func itemsDownloaded(items: NSArray)
}
class PostDataHandler: NSObject, NSURLSessionDataDelegate {
weak var delegate: PostDataHandlerProtocol!
var data : NSMutableData = NSMutableData()
//The path to the php script to be executed
let urlPath: String = "www.something.com/myphpscript.php"
func downloadItems() {
let url: NSURL = NSURL(string: urlPath)!
var session: NSURLSession!
let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
let task = session.dataTaskWithURL(url)
task.resume()
}
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
self.data.appendData(data);
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if error != nil {
print("Failed to download data")
}else {
print("Data downloaded")
self.parseJSON()
}
}
func parseJSON() {
var jsonResult: NSMutableArray = NSMutableArray()
do{
jsonResult = try NSJSONSerialization.JSONObjectWithData(self.data, options:NSJSONReadingOptions.AllowFragments) as! NSMutableArray
} catch let error as NSError {
print(error)
}
var jsonElement: NSDictionary = NSDictionary()
let posts: NSMutableArray = NSMutableArray()
for(var i = 0; i < jsonResult.count; i++)
{
jsonElement = jsonResult[i] as! NSDictionary
let post = PostModel()
//The following insures none of the JsonElement values are nil through optional binding
let username = jsonElement["username"] as? String
let imagePath = jsonElement["user_imagePath"] as? String
let postID = (jsonElement["post_id"] as! NSString).integerValue
let postRep = (jsonElement["post_rep"] as! NSString).integerValue
let postType = jsonElement["post_type"] as? String
let postDate = jsonElement["post_date"] as? String
let comment = jsonElement["comment"] as? String
post.username = username
post.imagePath = imagePath
post.postID = postID
post.postRep = postRep
post.postType = postType
post.postDate = postDate
post.comment = comment
posts.addObject(post)
}
dispatch_async(dispatch_get_main_queue(), {() -> Void in
self.delegate.itemsDownloaded(posts)
})
}
}
在我的視圖控制器,我創建了一個新的數據處理程序let postHandler = PostDataHandler()
,然後當視圖加載我打電話postHandler.downloadItems()
並在視圖控制器聲明我符合協議和實施itemsDownloaded:
func itemsDownloaded(items: NSArray) {
allPosts = items as! [PostModel]
indicator.stopAnimating()
self.tableVIew.reloadData()
}
有沒有人知道這是爲什麼發生?我試着看看有關這個錯誤的大量帖子,因爲我知道這很常見,但找不到任何幫助我的東西。許多帖子都說應該有一個檢查來確保它不是零,問題是我不認爲NSMutableArray可以是可選的,並且我檢查了所有的值,並且它們看起來不是零,所以那些答案沒有不幫我。在線程異常中,它說與閉包相關的東西,我認爲這可能會導致問題,但我不完全確定是什麼或如何。
NSMutableArray引用可以爲零(如果它是NSMutableArray?aka可選) –
nielsbot
嘗試用'?'替換'!'的所有實例並讓您的代碼以這種方式編譯。 – nielsbot
我在這裏有一個答案http://stackoverflow.com/a/35876779/210171 – nielsbot