Swift:self.init(coder:aDecoder)使用EXC_BAD_ACCESS导致应用崩溃 [英] Swift: self.init (coder : aDecoder) is crashing app with EXC_BAD_ACCESS

查看:184
本文介绍了Swift:self.init(coder:aDecoder)使用EXC_BAD_ACCESS导致应用崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用NSCoder和NSKeyArchiver时,错误导致应用崩溃.

Error is crashing app when using NSCoder and NSKeyArchiver.

我最近发表了一篇关于NSCoder的文章,但是从那以后,我改变了我的代码,并遇到了一个新的错误,并决定最好发表一篇新文章.

I had made a recent post around NSCoder but since then I've changed my code around and got a new error and decided a new post is best.

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

The app is a blog reader, reading from a MYSQL database using PHP to fill a table view with custom objects in Swift using JSON. I've been trying to save mainArray so that when the user moves cells across sections (each section has an array) it can save where the user left it.

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

Blog.swift: Handles the Blogs custom objects

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-表格视图所在的位置

MainController.swift - Where table view is located

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:),依此类推.

Looks like an infinite loop to me. You call init(coder:), and the first line calls init(coder:), and the first line calls init(coder:), and so on ad infinitum.

您需要在其中调用其他初始化程序.尝试使用self.init().

You need to call a different initializer inside it. Try self.init() instead.

这篇关于Swift:self.init(coder:aDecoder)使用EXC_BAD_ACCESS导致应用崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆