2017-07-25 3 views
1

Ich habe einen Fehler gemacht, den ich nicht finden kann. Das Array (Klassenebene) wird leer, kurz bevor es zurückgegeben wird.Array leer vor dem Beenden der Methode es

Ich versuche nur, auf seine Werte von anderen Teil des Codes zuzugreifen und kann es nicht tun, wie es leer wird. Ich kann die Array-Daten beim ersten Mal sehen, aber nicht im zweiten. Vielen Dank!

+0

Haben Sie das Array "self.userData" zugewiesen? –

+0

Was meinst du? userData befindet sich an der Spitze der Klasse. –

+0

vor dem Anhängen/vor der Verwendung der 'self.userData' müssen wir dieses Objekt zuweisen. –

Antwort

1

Erklärung der Frage des OP von @ the4kman Antwort erstreckt.

Ihr Code ist im Versand/Block. Der Dispatch/Block wird nach einiger Zeit aufgerufen.

So wird Ihr erster Druck sofort aufgerufen und zu diesem Zeitpunkt ist userdata leer. Aber im zweiten Fall wird der Ausdruck im Block aufgerufen und Sie ordnen die Daten der userData zu. Also, wenn der zweite Druck aufgerufen wird userdata Werte haben.

Bitte überprüfen Sie unten Code Ich erwähnt ersten und zweiten Druck, die entsprechend aufgerufen wird.

Für praktische, legen Sie Break-Punkte auf der Druckzeile und überprüfen Sie, welche Zeile wann aufgerufen wird.

let request = client.urlRequest(withMethod: "GET", url: userInfoURL, parameters: params, error: &clientError) 
client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in 
    if connectionError != nil { 
     print("Error: \(connectionError)") 
    } 

    do { 
     let json = JSON(data: data!) 
     if let userName = json["name"].string, 
      let description = json["description"].string, 
      let followersCount = json["followers_count"].int, 
      let favouritesCount = json["favourites_count"].int, 
      let followingCount = json["friends_count"].int, 
      let lang = json["lang"].string, 
      let nickname = json["screen_name"].string { 

      self.userData.append(userName) 
      self.userData.append(description) 
      self.userData.append(String(followersCount)) 
      self.userData.append(String(favouritesCount)) 
      self.userData.append(String(followingCount)) 
      self.userData.append(lang) 
      self.userData.append(nickname) 
      print(self.userData) // 2. print second 
     } 

    } 
} 
print(userData) // 1. print first 
} 

Erklärung der @ the4kman beantworten

Er verwendet die Callback heißt Rückruf verwendet wird, um Daten in der aufrufenden Funktion zu erhalten, wenn Sie Daten in der aufgerufenen Funktion empfangen. Hier verwendet er keine Parameter, aber Sie können Ihr Array senden.

Hinweis In Ihrer aufgerufenen Funktion erhalten Sie Daten im Block. Um Daten innerhalb des Blocks wie Ihre Situation zu erhalten, müssen Sie den Completionhandler verwenden.

Bitte nehmen Sie verweisen:

How does a completion handler work on iOS?

bearbeiten

in Ihrer func, wie diese Änderungen vornehmen.

func loadUserData(completion: (myArray: [String]) -> Void) { // my array is array of string. Assuming you'r passing array of string from closure. 

// Write the below line where you wanted to call callback or return through closure. 
// Recommandated to use below line in second print. 

    completion(userData) // 'userData' is the array which you wanted to pass from closure. 

} 

So rufen Sie die Schließung auf.

loadUserData { 
    (result: [String]) in 
    print("got back: \(result)") 
} 

Hinweis: können Sie Ihre Schließung @escaping ändern müssen sein, für diese x-Code, den Sie Vorschlag gibt. Also zuerst meine Antwort bearbeiten.

+0

Wie Sie sagen, habe ich es überprüft und die Drucke werden in der Reihenfolge aufgerufen, die Sie erwähnen. Wie könnte ich das dann lösen? –

+0

@ JavierSanzRozalén Bitte überprüfen Sie meine aktualisierte Antwort, die ich bereits erwähnt habe. –

+0

Aber was, wenn ich dieses Array von überall zurückgeben möchte? Ich bin steckengeblieben, da ich noch nie Verschlüsse benutzt habe und ich bin ein Neuling bei Swift. Entschuldige, dass du gefragt hast. –

3

client.sendTwitterRequest ist eine asynchrone Anforderung, die eine Netzwerkverbindung erfordert. Es wird Zeit brauchen, um zu verarbeiten.

Sie sollten eine Sperrung angeben, die userData zurückgibt und auf sie zugreifen, wenn die Anforderung zurückgegeben wird.

private func loadUserData(_ callback: @escaping() ->()) { 
    // We're getting user info data from JSON response 
    let session = Twitter.sharedInstance().sessionStore.session() 
    let client = TWTRAPIClient.withCurrentUser() 
    let userInfoURL = "https://api.twitter.com/1.1/users/show.json" 
    let params = ["user_id": session?.userID] 
    var clientError : NSError? 
    let request = client.urlRequest(withMethod: "GET", url: userInfoURL, parameters: params, error: &clientError) 
    client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in 
     if connectionError != nil { 
      print("Error: \(connectionError)") 
     } 

     do { 
      let json = JSON(data: data!) 
      if let userName = json["name"].string, 
       let description = json["description"].string, 
       let followersCount = json["followers_count"].int, 
       let favouritesCount = json["favourites_count"].int, 
       let followingCount = json["friends_count"].int, 
       let lang = json["lang"].string, 
       let nickname = json["screen_name"].string { 

       self.userData.append(userName) 
       self.userData.append(description) 
       self.userData.append(String(followersCount)) 
       self.userData.append(String(favouritesCount)) 
       self.userData.append(String(followingCount)) 
       self.userData.append(lang) 
       self.userData.append(nickname) 

       callback()  
      } 
     } 
    } 
} 

func manageUserData() { 
    loadUserData() { 
     print(userData) 
    } 
} 
+0

Immer noch das gleiche Problem. In dem Codeabschnitt, den ich gepostet habe, habe ich kein Problem, wenn das Array zum ersten Mal gedruckt wird, aber in der zweiten. Irgendeine Idee ? –

Verwandte Themen