5
votes

Quelle est la manière la plus simple d'instancier un nouvel objet Codable dans Swift?

J'ai une classe Codable:

let newTask = Task()
allTasks.append(newTask)

Quand j'essaye de l'instancier:

class Task: Codable {
    var name: String
}

Cela me donne une erreur: p >

Argument manquant pour le paramètre "from" dans l'appel

Tout ce que je veux, c'est insérer un nouvel objet (newTask) dans un tableau. Quelle est la manière la plus simple de procéder?


1 commentaires

pourquoi voulez-vous utiliser codable si vous n'utilisez aucune clé de codage?


5 Réponses :


2
votes

Votre classe Task ne fournit pas son propre initialiseur donc il obtient celui défini dans le protocole Codable (qu'il obtient du code Decodable protocole).

Ajoutez votre propre init explicite qui prend un paramètre name ou changez votre classe en struct. Dans tous les cas, vous devez créer une Tâche en transmettant une valeur de nom afin que la propriété name puisse être initialisée.

Rien de tout cela ne résout le fait que le code que vous avez publié n'utilise pas Codable donc peut-être qu'il n'est pas nécessaire que votre classe (ou structure) se conforme à Codable .


0 commentaires

4
votes

Vous pouvez hériter de l'initialiseur de NSObject:

class Task: Codable {
    var name: String

    init(withName name: String) {
        self.name = name
    }
}
let newTask = Task(withName: "ikevin8me")

Si vous ne voulez pas hériter de NSObject, créez simplement votre propre initialiseur:

class Task: Codable {
    var name: String?

    init() {

    }
}


6 commentaires

OK, veuillez consulter la réponse modifiée. La variable name a besoin d'une valeur par défaut. Sinon, il n'est pas lancé avant que l'auto ne soit attribué.


OK, ça marche mais ce n'est vraiment pas la meilleure solution. Il apporte inutilement NSObject et tout le bagage Objective-C avec lui. Et attribuer par défaut le nom à la chaîne vide est très non-Swifty.


Ensuite, écrivez votre propre initialiseur.


J'ai ajouté un exemple sans hériter de NSObject.


Si vous ne voulez pas de chaîne vide, vous pouvez rendre la chaîne facultative ou vous devez l'initialiser avec quelque chose dans init (). J'ai changé le deuxième exemple pour le rendre facultatif.


Soit dit en passant, votre question est de savoir quelle est la manière la plus simple d’instancier un objet Codeable , et je crois que mon premier exemple n’est que cela - c’est sans doute la réponse la plus simple ici et vous peut, bien sûr, changer le nom var en option si vous n'aimez pas le prérégler.



0
votes

La classe Task ne fournit aucun initialiseur pour initialiser un objet, c'est pourquoi elle prend l'initialiseur du protocole Codable , fournissez votre propre initialiseur pour initialiser un objet.

Utilisation:

1. avec la classe

struct Task: Codable {
    var name: String
}

let task = Task(name: "jarvis")

2. avec la structure:

class Task: Codable {
    var name: String
    init(_ name : String) {
        self.name = name
    }
}

var task = Task("Jarvis")


6 commentaires

Pourquoi avez-vous déplacé implicitement la propriété name ? Ne faites pas cela inutilement.


@rmaddy J'espère qu'il sera initialisé correctement.


Mise à jour ... Pouvez-vous dire pourquoi vous avez si peur de '!' ;)


Je n'en ai pas peur. Je vous signale que vous ne devriez pas l'utiliser quand ce n'est pas approprié. Il n'y en a pas besoin ici.


@JarvisTheAvenger Il y a quelques situations très spécifiques où vous devez utiliser des options implicitement non emballées . La plupart du temps, c'est inutile ou cela risque de planter votre application, ce qui semble être une chose raisonnable dont il faut avoir "peur".


@JohnMontgomery Yup ... C'est la beauté du débordement de pile. nous apprenons à collaborer. Merci.



0
votes

Une autre solution consiste à utiliser struct

struct Task: Codable {
    var name: String
}

let task = Task(name: "myname")


0 commentaires

0
votes

Je n'attribuerais pas de valeur par défaut à la propriété mais implémenterais la méthode d'initialisation attendue et une variante pratique qui ne prendrait aucun argument ou j'aurais une méthode d'usine qui crée une tâche "vide"

Voici le code avec les deux options

class Task: Codable {
    var name: String

    init(_ name: String) {
        self.name = name
    }

    convenience init() {
        self.init("")
    }

    static func emptyTask() -> Task {
        return Task("")
    }
}


0 commentaires