[RESOLU] [SWIFT] Problème perte de référence

InsouInsou Membre
juillet 2016 modifié dans API UIKit #1

Bonjour,


 


Nouvelle journée, nouveau problème  :p


 


Cette fois ci, celui là  m'inquiète un peu plus que les autres..


 


Je vais essayé d'être assez explicite parce que ça ne me parait pas simple..


 


Premièrement, mon application liste des catégories (que je récupère via json et que j'affiche dans un tableView, lorsqu'on clic sur une catégorie, on transite vers un autre tableView qui liste les fiches qu'il y a dedans et lorsqu'on clic sur un bouton, on peut ajouter une nouvelle fiche et on se retrouve sur un formulaire Eureka.. ça, c'est pour avoir le cheminement en tête ^^


 


A chaque fois qu'on arrive sur la liste des catégories, il y a un refresh qui se fait pour rafraichir la liste des fiches, pour ça, j'utilise cette fonction (qui se trouve dans mon ListeCategorieViewController.swift) :



func chargeLesFichesDeLaCategorie(IdCat : String){
// Charge les fiches - DEBUT

// blablabla, récupération des paramètres ici

// requete Json Synchrone
let recupJsonSync = Alamofire.request(.POST, MONURLICI, parameters: Paramètres).responseJSON()

switch recupJsonSync.result {
case .Success:
if let value = recupJsonSync.result.value {
let recupJSON = JSON(value)
if(recupJSON["Error","Code"] == 0){
// OK
if let resData = recupJSON["Data"].arrayObject {
self.ArrayFiches = resData as! [[String:AnyObject]] // Attribut le json au ArrayCategories
}
if self.ArrayFiches.count > 0 {
//print("OK3")
self.tableFiches.reloadData() // recharge le tableau
}
}
else{
// PAS OK
}
}
case .Failure(let error):
// PAS OK 2
}
// Charge les fiches - FIN
}

La ligne importante est self.tableFiches.reloadData()


Lorsque je passe dedans normalement (c'est à  dire à  l'ouverture d'une catégorie, ou en faisant un PullToRefresh), dans mon debugger, j'ai ça :


 


547485Good.png


 


J'ai bien une référence sur mon tableFiches.


 


Le soucis intervient quand je sauvegarde une nouvelle fiche, une fois inscrite dans ma bdd, mon json me renvoie que c'est bon.. du coup dans mon nouvelleFicheViewController.swift, au retour de mon json, je comptais simplement faire un :



let recupJsonSync = Alamofire.request(.POST, MONURLICI, parameters: Paramètres).responseJSON()

switch recupJsonSync.result {
case .Success:
if let value = recupJsonSync.result.value {
let recupJSON = JSON(value)
if(recupJSON["Error","Code"] == 0){
self.dismissViewControllerAnimated(true, completion: nil) // On ferme la fenetre
ListeCategorieViewController().chargeLesFichesDeLaCategorie(self.idCategorie) // Charge les catégories
}
else{
// PAS OK
}
}
case .Failure(let error):
// PAS OK 2
break
}

La ligne importante est : ListeCategorieViewController().chargeLesFichesDeLaCategorie(self.idCategorie)


Pour moi, il reprend la classe ListeCategorieViewController et execute la fonction chargeLesFichesDeLaCategorie() (pour rafraichir la liste des fiches et faire apparaitre la nouvelle fiche ajoutée)


 


Sauf que dans le debugger, je me retrouve avec ça : 


 


383020ErreurNil.png


 


Il a perdu la référence au tableFiche et je ne sais pas pourquoi..


 


Est-ce-que je m'y prends mal ? Pourquoi perd-il la référence a tableFiche ?


Une idée ? Une piste ?  :o


 


Merci de votre aide encore une fois ^^


Mots clés:

Réponses

  • LarmeLarme Membre

    Quelle est la déclaration de tableFiches?


  • InsouInsou Membre

    Euhmmm ?? 


    ça ?



    @IBOutlet weak var tableFiches: UITableView!

    Dans ListeCategorieViewController


  • Joanna CarterJoanna Carter Membre, Modérateur

    Tu as connecté la tableFiche à  la UITableView dans le XIB ou storyboard?


  • InsouInsou Membre

    Genre ça ?


     


    768057Tableview.png


  • Joanna CarterJoanna Carter Membre, Modérateur

    Oui, mais c'est inutile de faire une autre référence; il y a déjà  une référence qui s'apelle tableView dans le UITableViewController.


  • InsouInsou Membre


    Oui, mais c'est inutile de faire une autre référence; il y a déjà  une référence qui s'apelle tableView dans le UITableViewController.




     


    Est-ce-que tu peux être plus explicite sur ça ?


    Parce que je comprends pas trop où tu vois plusieurs référence..


    Pour moi, de mémoire, j'ai glissé le tableFiches (du storyboard) dans la partie code (dans ListeCategorieViewController) pour créer un @IBOutlet (appelé tableFiches)


    Du coup, il n'y a qu'une référence nan ?

  • Joanna CarterJoanna Carter Membre, Modérateur

    Est-ce que tu as mis la UITableView dans un UIViewController ou un UITableViewController ?


  • InsouInsou Membre

    class ListeCategorieViewController: UIViewController {

    @IBOutlet weak var tableFiches: UITableView!
    ...
    ...

    }

    Donc je dirai dans un UIViewController.. nan ?


  • Joanna CarterJoanna Carter Membre, Modérateur
    juin 2016 modifié #10

    Bah non ! Le UITableViewController est bien conçu juste pour gérer les UITableView. Il ne faut qu'en poser un dans le storyboard et, piff, paff, pouff ! tous est déjà  connecté ; il ne reste que overrider les méthodes de delegate et dataSource


  • InsouInsou Membre
    juin 2016 modifié #11

    Donc si je comprends bien, je dois remplacer mon UITableView par un UITableViewController dans mon storyboard ? (et remettre mon code dans une classe refaite pour le UITableViewController..) ... c'est ça ?


     


    Edit : En relisant, j'ai pas l'impression que j'ai bien compris le truc..


  • Joanna CarterJoanna Carter Membre, Modérateur

    Presque. tu dois remplacer le UIViewController par un UITableViewController. ça vient avec le UITableView déjà  la dedans. Et oui, pour dériver ta classe de UITableViewController.


  • Quand tu dis : 



    tu dois remplacer le UIViewController par un UITableViewController.



     


    Tu parles dans le storyboard ?


    Ou dans l'entête de ma class ?



    class ListeCategorieViewController: UITableViewController { ???

    J'aurai tendance à  dire dans le storyboard mais je préfère être sûr avant de faire n'importe quoi :s


  • Joanna CarterJoanna Carter Membre, Modérateur

    Oui, dans le storyboard et dans le code


  • J'ai l'impression que je ne peux pas faire ce changement sans tout pété et j'avoue que j'ai pas spécialement le temps de me plonger dans une tel refonte pour le moment :s


     


    Juste une idée comme ça.. est-ce-que je ne peux pas donner un identifiant à  la tableView et lors de l'erreur, je test avec :



    if(self.tableFiches != nil){ // si tableFiches n'est pas nil
    self.tableFiches.reloadData() // recharge le tableau
    }
    else{
    print("TableFiche == nil")
    // recharger ici le tableFiche ??
    // puis reloadData
    }

    et lorsqu'il est à  nil, je le ré-attribut pour ensuite le recharger ?


     


    Je ne sais pas si c'est faisable mais c'est pour avoir une rustine en attendant..


  • Joanna CarterJoanna Carter Membre, Modérateur
    juin 2016 modifié #16

    Tu accumuleras une dette technique très vite si tu continues comme ça. C'est pas grande chose de remplacer un view controller dans un storyboard et de changer l'héritage d'une classe.


     


    Crois moi, ça vaut la peine !


     


    En plus, si ta référence devient nil, tu as des gros soucis, peut-être ailleurs.


  • De ce que je comprends du code, tu essayes d'appeler une méthode d'instance d'un Controller à  partir d'un nouveau Contrôler. Le problème ici est la ligne :


     



     


     


    ListeCategorieViewController().chargeLesFichesDeLaCategorie(self.idCategorie)

     


    Tu crées une nouvelle instance de ta ListeController. Or le init n'a pas encore créer tes outlet y compris ta TableView.


     


    Ce que tu dois faire par exemple c'est créer un délégué qui va informer ta liste qu'il doit rafraà®chir.


  • InsouInsou Membre
    juillet 2016 modifié #18

    Ah oui en effet, je créé une nouvelle instance, j'suis con, j'avais pas compris ça comme ça, du coup c'est logique que je n'ai aucune référence..


     



     


    Ce que tu dois faire par exemple c'est créer un délégué qui va informer ta liste qu'il doit rafraà®chir.



     


    Dac'.. et comment je fais pour faire ça ? :s


  • Bon alors, j'ai fais un truc qui marche mais j'ai pas l'impression que ce soit avec un délégué..


     


    En gros, dans la vue ListeCategorieViewController.swift, je créé un tableau qui contient mon UITableView que j'envoi à  l'autre vue..



    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    switch segue.identifier! {

    case "versNouvelleFiche":
    // envoi les données vers l'autre vue
    TabInfosTableView = [
    "ListeFiche" : tableFiches
    ]
    let svc = segue.destinationViewController as! UINavigationController
    let addEventViewController = svc.topViewController as! nouvelleFicheViewController
    addEventViewController.TabInfosTableView = TabInfosTableView

    default:
    break
    }
    }

    Dans ma vue nouvelleFicheViewController.swift, je declare la variable pour stocker mon IUTableView



    var TabInfosTableView : [String:UITableView]? = [:] 

    Et dans mon code du premier post, après la sauvegarde de la fiche, j'ai remplacé :



    ListeCategorieViewController().chargeLesFichesDeLaCategorie(self.idCategorie) // Nouvelle instance donc pas bon ! 

    par :



    self.TabInfosTableView!["ListeFiche"]!.startPullToRefresh() // J'ai maintenant accès aux fonctions du tableView

     J'suis pas sûr que ce soit la meilleure manière de faire mais bon..


  • colas_colas_ Membre
    juillet 2016 modifié #21
    Attention, pas de capitale en début de nom d'une variable.


    ---> tabInfosViewController


    (J'ai pas suivi le fil, ta solution a l'air ok.)
Connectez-vous ou Inscrivez-vous pour répondre.