2017-06-13 8 views
0

Erreur se bloque application lorsque vous utilisez NSCoder et NSKeyArchiver. J'ai fait un post récent autour de NSCoder mais depuis, j'ai changé mon code et j'ai eu une nouvelle erreur et j'ai décidé qu'un nouveau post est le meilleur.Swift: self.init (codeur: aDecoder) se bloque application avec EXC_BAD_ACCESS

L'application est un lecteur de blog, la lecture à partir d'une base de données MYSQL en utilisant PHP pour remplir une vue de table avec des objets personnalisés dans Swift en utilisant JSON. J'ai essayé de sauvegarder mainArray de sorte que lorsque l'utilisateur déplace des cellules entre les sections (chaque section a un tableau), il peut enregistrer où l'utilisateur l'a laissé.

Blog.swift: gère les blogs des objets personnalisés

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 - Où vue de la table se trouve

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") 
    } 
} 
+0

vous vouliez écrire 'super.init'? 'self.init' semble être une boucle infinie. – luk2302

+0

Je sais que EXC_BAD_ACCESS est la gestion de la mémoire. Peut-il être parce que c'est une boucle infinie? Comment puis-je appliquer super.init? – BroSimple

+1

soit laisser tomber le init-appel ou simplement remplacer l'auto avec des super dans cette ligne – luk2302

Répondre

1

On dirait une boucle infinie pour moi. Vous appelez init(coder:) et la première ligne appelle init(coder:) et la première ligne appelle init(coder:), et ainsi de suite ad infinitum.

Vous devez appeler un initialiseur différent à l'intérieur. Essayez plutôt self.init().

+1

Ça marche! Il suffit de supprimer le 'coder: aDecoder' de 'self.init()' comme vous l'avez dit. – BroSimple

1

Comme d'autres l'ont dit, c'est en effet une boucle infinie. Ce que vous devez faire est de le changer en self.init() et aussi ajouter ce qui suit à votre code. Ou implémentez votre propre init qui fait tout ce qui doit être fait.

override init() { 
    super.init() 
}