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?
5 Réponses :
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
.
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() { } }
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.
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")
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.
Une autre solution consiste à utiliser struct
struct Task: Codable { var name: String } let task = Task(name: "myname")
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("") } }
pourquoi voulez-vous utiliser codable si vous n'utilisez aucune clé de codage?