2016-05-18 8 views
3

Ich versuche, eine Funktion reloadTable in meinem HomeViewController von meiner Task-Klasse aufzurufen. Aber ich werde weiter geworfenWie Funktion von einem anderen ViewController aufgerufen wird

Verwendung von Instanz Mitglied 'ReloadTable' auf den Typ 'HomeViewController'; meinst du stattdessen einen Wert vom Typ 'HomeViewController'?

Das ist mein HomeViewController Code:

import UIKit 
import Alamofire 
import SwiftyJSON 

class HomeViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 
func reloadTable() { 
    self.displayTask.reloadData() 
} 
} 

Das ist meine Aufgaben Klasse:

import Foundation 
import Alamofire 
import SwiftyJSON 
class Tasks { 

static let sharedInstance = Tasks() 

var datas: [JSON] = [] 

func getTaskDetails(){ 
    Alamofire.request(.GET, Data.weeklyEndpoint).validate().responseJSON { response in 
     switch response.result { 
     case .Success(let data): 
      let json = JSON(data) 

      if let buildings = json.array { 
       for building in buildings { 
        if let startDate = building["start_date"].string{ 
         print(startDate) 
        } 
        if let tasks = building["tasks"].array{ 

         Tasks.sharedInstance.datas = tasks 

         HomeViewController.reloadTable() 

         for task in tasks { 
          if let taskName = task["task_name"].string { 
           print(taskName) 
          } 
         } 
        } 
       } 
      } 



     case .Failure(let error): 
      print("Request failed with error: \(error)") 
     } 
    } 

} 

// for prevent from creating this class object 
private init() { } 


} 

Antwort

0

Wie viele der anderen Antworten angeben, versuchen Sie, auf eine statische Funktion auf einer statischen Referenz zuzugreifen.

Ich würde vorschlagen, die Verwendung von Verschlüssen, betrachten Sie Folgendes; Erstellen Sie eine Schließung für .Success und die .Failure, dies ermöglicht Ihnen, entsprechend dem Ergebnis der Datenanforderung zu handeln. Die onError Schließung ist als optional definiert, das heißt, Sie müssen die onError im Funktionsaufruf'getTaskDetails` nicht implementieren, implementieren Sie es, wo Sie glauben, dass Sie die Fehlerinformationen benötigen.

func getTaskDetails(onCompletion: ([Task]) ->(), onError: ((NSError) ->())? = nil) { 

    Alamofire.request(.GET, Data.weeklyEndpoint).validate().responseJSON { 
     response in 

     switch response.result { 
      case .Success(let data): 
      let json = JSON(data) 

      if let buildings = json.array { 
       for building in buildings { 
        if let startDate = building["start_date"].string{ 
         print(startDate) 
        } 
        if let tasks = building["tasks"].array{ 

         Tasks.sharedInstance.datas = tasks 

         onCompletion(tasks) 
        } 
       } 
      } 

      case .Failure(let error): 
      print("Request failed with error: \(error)") 
      onError?(error) 
     } 
    }  
} 

Von Ihrem HomeViewController:

// Call from wherever you want to reload data. 
func loadTasks(){ 

    // With error handling. 
    // Fetch the tasks and reload data. 
    Tasks.sharedInstance.getTaskDetails({ 
     tasks in 

     self.displayTask.reloadData() 
    }, onError: { 
     error in 

     // Handle error, display a message or something. 
     print(error) 
    }) 


    // Without error handling. 
    // Fetch the tasks and reload data. 
    Tasks.sharedInstance.getTaskDetails({ 
     tasks in 

     self.displayTask.reloadData() 
    }) 
} 

Basics

Closures

+0

Hallo @Laffen, warum hast du Completion: ([Task]) ->()? Ich bin mir nicht sicher, wie das funktioniert – noobdev

+0

Ich würde dir empfehlen, einen Blick auf den 'Closures'-Link zu werfen, den ich zur Verfügung gestellt habe. Die Dokumentation wird im Detail erklären, was/wie und warum. Sie definieren die 'onCompletion' für Ihre Funktion, die Sie schließen möchten; Sie rufen die onCompletion innerhalb dieser Funktion auf, in der die angeforderten Daten zurückgegeben werden. Wenn Sie die'getTaskDetails'aufrufen, definieren Sie den Rumpf der 'onCompletion'-Anweisung. Hier teilen Sie der Schließung mit, was sie tun soll, wenn sie innerhalb der definierten Funktion aufgerufen wird. Das wurde ein bisschen haarig ... – Laffen

0

Make Klasse Aufgabe als Struct, Funktion getTaskDetails als statische und versuchen Funktion getTaskDetails zu nennen () in HomeViewController. Als Ergebnis dieser Funktion verwenden Sie realoadTable()

-1

In HomeViewController haben Sie reloadTable() als Instanzmethode und nicht als Klassenfunktion definiert. Sie sollten reloadTable() aufrufen, indem Sie eine Instanz von HomeViewController als HomeViewController() erstellen. Ersetzen

HomeViewController.showLeaderboard() 
HomeViewController().showLeaderboard() 

Ich hoffe, es hilft. Glückliche Kodierung.

+0

sicher sind, wird es funktionieren? – raki

+0

Nicht versucht, aber logisch Ja. Übrigens bevorzuge ich in solchen Fällen persönlich Benachrichtigungsmuster darüber. – luckyShubhra

+0

wird es nicht funktionieren, weil View Controller eine Instanz von HomeViewController hat, aber wenn Sie HomeViewController() aufrufen, erstellt es eine andere Instanz und unterscheidet sich von der Instanz des ViewCotrollers. – raki

0

In diesem Fall ist reloadTable() eine Instanzmethode. Sie können es nicht nach Klassennamen aufrufen, Sie müssen ein Objekt für HomeViewController erstellen und dann müssen Sie diese Methode aufrufen, indem Sie dieses Objekt verwenden.

Aber in dieser Situation muss die Methode nicht direkt aufgerufen werden, indem HomeViewController Objekt verwendet wird. Sie können dies durch NSNotification Verwendung in einer anderen Art und Weise tun

Mit NSNotification:

eine Benachrichtigung Beobachter hinzufügen für Ihre HomeViewController

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(HomeViewController.reloadTable), name:"ReloadHomeTable", object: nil)

Fügen Sie die obigen Zeilen in Ihrem viewDidLoad Methode von HomeViewController

Ersetzen Sie jetzt diese Zeile HomeViewController.reloadTable() durch NSNotificationCenter.defaultCenter().postNotificationName("ReloadHomeTable", object: nil) in Ihrem Task Klasse

+0

Vergessen Sie nicht, den Beobachter zu entfernen. – Laffen

+0

Aber ich frage mich, wo den Beobachter zu entfernen? viewDidUnload ist jetzt nicht verfügbar. Aber manchmal müssen wir die Daten aktualisieren, selbst wenn die Ansicht verschwunden ist. – raki

+0

Wenn Sie den Ansichtscontroller vom Stapel entfernen möchten, sollten Sie die Beobachter für diese Ansicht entfernen. Innerhalb des 'disneyViewController (_ :)' oder ähnlichem. – Laffen

Verwandte Themen