Swift:self.init(coder:aDecoder)与EXC_BAD_ACCESS碰撞应用程序
使用NSCoder和NSKeyArchiver时出现错误应用程序崩溃。Swift:self.init(coder:aDecoder)与EXC_BAD_ACCESS碰撞应用程序
我在NSCoder周围发了一篇最近的文章,但自那时起我改变了我的代码,并得到一个新的错误,并决定一个新的帖子是最好的。
该应用程序是一个博客阅读器,从使用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()'中删除'coder:aDecoder'。 – BroSimple
正如其他人所说,这确实是一个无限循环。你需要做的是将其更改为self.init(),并将以下代码添加到代码中。或者实现你自己的init来完成任何需要完成的任务。
override init() {
super.init()
}
你想写'super.init'吗? 'self.init'好像是一个无限循环。 – luk2302
我知道EXC_BAD_ACCESS是内存管理。这是因为它是一个无限循环吗?我如何申请super.init? – BroSimple
要么删除初始化调用,要么简单地用自己的super替换该行 – luk2302