Swift:self.init(coder:aDecoder)正在崩溃与EXC_BAD_ACCESS的应用程序

使用NSCoder和NSKeyArchiver时,错误是崩溃的应用程序。

在这里输入图像说明 我在NSCoder上做了一个最近的post,但自那以后,我改变了我的代码,并得到一个新的错误,并决定一个新的职位是最好的。

该应用程序是一个博客阅读器,从使用PHP的MYSQL数据库中读取,以使用JSON在Swift中使用自定义对象填充表视图。 我一直在试图保存mainArray,以便当用户移动单元跨过部分(每个部分都有一个数组)时,它可以保存用户离开它的地方。

Blog.swift:处理博客自定义对象

import UIKit class Blog: NSObject, NSCoding { var blogName: String! var blogStatus1: String! var blogStatus2: String! var blogURL: String! var blogID: String! var blogType: String! var blogDate: String! var blogPop: String! static func createBlog(from jsonObject: AnyObject) -> Blog? { guard let bID: String = jsonObject.object(forKey: "id") as? String, let bName: String = jsonObject.object(forKey: "blogName") as? String, let bStatus1: String = jsonObject.object(forKey: "blogStatus1") as? String, let bStatus2: String = jsonObject.object(forKey: "blogStatus2") as? String, let bURL: String = jsonObject.object(forKey: "blogURL") as? String, let bType: String = jsonObject.object(forKey: "blogType") as? String, let bDate: String = jsonObject.object(forKey: "blogDate") as? String, let bPop: String = jsonObject.object(forKey: "blogPop") as? String else { print("Error: (Creating Blog Object)") return nil } let blog = Blog() blog.blogName = bName blog.blogStatus1 = bStatus1 blog.blogStatus2 = bStatus2 blog.blogURL = bURL blog.blogID = bID blog.blogType = bType blog.blogDate = bDate blog.blogPop = bPop return blog } // NSCoding convenience required init?(coder aDecoder: NSCoder) { self.init (coder : aDecoder) // *** Crashes Here *** self.blogName = aDecoder.decodeObject(forKey: "blogName") as! String self.blogStatus1 = aDecoder.decodeObject(forKey: "blogStatus1") as! String self.blogStatus2 = aDecoder.decodeObject(forKey: "blogStatus2") as! String self.blogURL = aDecoder.decodeObject(forKey: "blogURL") as! String self.blogID = aDecoder.decodeObject(forKey: "blogID") as! String self.blogType = aDecoder.decodeObject(forKey: "blogType") as! String self.blogDate = aDecoder.decodeObject(forKey: "blogDate") as! String self.blogPop = aDecoder.decodeObject(forKey: "blogPop") as! String } func encode(with aCoder: NSCoder) { aCoder.encode(blogName, forKey: "blogName") aCoder.encode(blogStatus1, forKey: "blogStatus1") aCoder.encode(blogStatus2, forKey: "blogStatus2") aCoder.encode(blogURL, forKey: "blogURL") aCoder.encode(blogID, forKey: "blogID") aCoder.encode(blogType, forKey: "blogType") aCoder.encode(blogDate, forKey: "blogDate") aCoder.encode(blogPop, forKey: "blogPop") } } 

MainController.swift – 表视图所在的位置

 var mainArray = [Blog]() var followedArray = [Blog]() override func viewDidLoad() { super.viewDidLoad() // Receiving Data from Server retrieveData() if let data = UserDefaults.standard.data(forKey: "mainArrayKey"), let myBlogList = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Blog] { mainArray = myBlogList print("mainArray: \(mainArray)") } else { print("Error: (Saving to UserDefaults)") } } // Retrieving Data from Server func retrieveData() { let getDataURL = "http://example.com/receiving.php" let url: NSURL = NSURL(string: getDataURL)! do { let data: Data = try Data(contentsOf: url as URL) let jsonArray = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSMutableArray // Looping through jsonArray for jsonObject in jsonArray { if let blog = Blog.createBlog(from: jsonObject as AnyObject) { mainArray.append(blog) // Save to UserDefaults let encodedData = NSKeyedArchiver.archivedData(withRootObject: mainArray) UserDefaults.standard.set(encodedData, forKey: "mainArrayKey") } } } catch { print("Error: (Retrieving Data)") } myTableView.reloadData() // Logs print("This is mainArray", mainArray) // Check UserDefaults if UserDefaults.standard.object(forKey: "mainArrayKey") != nil{ print("mainArray key exists") } else { print("mainArray key does not exist") } } 

看起来像一个无限循环给我。 你可以调用init(coder:) ,第一行调用init(coder:) ,第一行调用init(coder:) ,等等。

你需要调用一个不同的初始化器。 尝试self.init()代替。

正如其他人所说,这确实是一个无限循环。 你需要做的是将其更改为self.init(),并将下面的代码添加到您的代码中。 或者实现你自己的init,做任何需要做的事情。

 override init() { super.init() }