在展开可选值-NSMutableArray-Swift时意外发现nil
我从数据库中检索新闻提要的数据处理程序中的帖子,运行php脚本并将JSON编码的数据回显到我的应用程序中,此时数据被解析并存储在“帖子”的模型中,视图控制器中使用一个协议在数据下载后获取数据。我的问题是,当我将NSMutableArray的“post”对象传递给函数“itemsDownloaded”(即协议的函数)时,出现了臭名昭著的“在展开可选值时意外发现零”错误。我检查了所有被解析的值,并且它们都存在,我还检查了数组的计数,以确保它有值。异常发生在行在展开可选值-NSMutableArray-Swift时意外发现nil,swift,null,protocols,Swift,Null,Protocols,我从数据库中检索新闻提要的数据处理程序中的帖子,运行php脚本并将JSON编码的数据回显到我的应用程序中,此时数据被解析并存储在“帖子”的模型中,视图控制器中使用一个协议在数据下载后获取数据。我的问题是,当我将NSMutableArray的“post”对象传递给函数“itemsDownloaded”(即协议的函数)时,出现了臭名昭著的“在展开可选值时意外发现零”错误。我检查了所有被解析的值,并且它们都存在,我还检查了数组的计数,以确保它有值。异常发生在行self.delegate.itemsdo
self.delegate.itemsdownload(posts)
处理数据的代码如下所示:
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)
})
}
}
有人知道为什么会这样吗?我试图查看大量关于这个错误的帖子,因为我知道这很常见,但找不到任何对我有帮助的东西。许多帖子说应该进行检查以确保它不是零,问题是我不认为NSMutableArray可以是可选的,而且我检查了所有的值,它们看起来不是零,所以这些答案对我没有帮助。在线程异常中,它说了一些与闭包相关的东西,我认为这可能会导致问题,我只是不确定是什么或如何造成的 您显示的代码中没有一个将PostDataHandler的
委托
属性设置为任何值,因此可以合理地假设它仍然是nil
,这很好地解释了当您试图像实际对象一样访问它时为什么会在运行时崩溃。NSMutableArray引用可以是nil(如果是NSMutableArray?又称可选)尝试将!
的所有实例替换为?
并以这种方式编译代码。我这里有一个答案愚蠢!愚蠢!愚蠢!谢谢。我在视图控制器中设置了委托。将在6分钟内标记为正确。这可能发生在任何人身上。如果你犯了错误,它没有充分考虑该行中的内容ght可以想象为nil
。因为委托
是第一个,所以这是我考虑的第一件事!:)
func itemsDownloaded(items: NSArray) {
allPosts = items as! [PostModel]
indicator.stopAnimating()
self.tableVIew.reloadData()
}