2015-08-20 18 views
36

Tôi đã lướt qua các câu hỏi StackOverflow cố gắng tìm ra nơi tôi đang sai với mã của tôi, nhưng tôi dường như không thể! Tôi đang cố gắng chuyển đổi dự án Swift 1.2 của mình sang Swift 2.0 và đang gặp vấn đề với lớp của tôi tải xuống dữ liệu JSON.Giá trị trả lại không mong đợi không có giá trị trong chức năng Void (Swift 2.0)

Tôi liên tục nhận được lỗi Giá trị trả về không trống không mong đợi trong hàm void.

Đây là mã, phần nào bị cắt ngắn, mà tôi đang sử dụng;

... 

class func fetchMinionData() -> [Minion] { 

    var myURL = "http://myurl/test.json" 

    let dataURL = NSURL(string: myURL) 

    let request = NSURLRequest(URL: dataURL!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0) 

    let session = NSURLSession.sharedSession() 

    session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in 
     let minionJSON = JSON(data!) 

     var minions = [Minion]() 

     for (_, minionDictionary) in minionJSON { 
      minions.append(Minion(minionDetails: minionDictionary)) 
     } 

     return minions 
     //THIS IS WHERE THE ERROR OCCURS 

    }).resume() 
} 

... 

Có lẽ tôi đang xem cái gì đó đơn giản, nhưng tôi không chắc tại sao chức năng của tôi bị coi là vô hiệu. Bất kỳ suy nghĩ nào sẽ được đánh giá vô cùng! Cảm ơn bạn!

Trả lời

52

Bạn có một vấn đề bởi vì dòng của bạn:

return minions 

không trở về từ chức năng của bạn. Thay vào đó, nó trả về từ trình xử lý hoàn thành trong dataTaskWithRequest. Và nó không nên làm như vậy bởi vì đóng cửa đó là một hàm rỗng.

Sự cố mà bạn có kết quả từ thực tế là dataTaskWithRequest là một hoạt động không đồng bộ. Điều đó có nghĩa là nó có thể trở lại sau khi thực hiện chức năng của bạn.

Vì vậy, bạn cần phải thay đổi mẫu thiết kế của mình.

Một cách để làm điều đó sẽ là như sau:

static var minions:[Minion] = [] { 
    didSet { 
     NSNotificationCenter.defaultCenter().postNotificationName("minionsFetched", object: nil) 
    } 
} 



class func fetchMinionData() { 

    var myURL = "http://myurl/test.json" 
    let dataURL = NSURL(string: myURL) 
    let request = NSURLRequest(URL: dataURL!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0) 

    let session = NSURLSession.sharedSession() 

    session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in 
     let minionJSON = JSON(data!) 

     var minions = [Minion]() 

     for (_, minionDictionary) in minionJSON { 
      minions.append(Minion(minionDetails: minionDictionary)) 
     } 

     self.minions = minions 
     //THIS IS WHERE THE ERROR OCCURS 

    }).resume() 
} 

Sau đó, trước khi gọi chức năng của bạn, bạn nên đăng ký để lắng nghe NSNotification với tên "minionsFetched". Và chỉ sau khi bạn nhận được thông báo đó, bạn nên xử lý các tay sai như thể chúng được tìm nạp.

+0

Điều đó có ý nghĩa với tôi. Nhưng nếu tôi di chuyển dòng 'return minions' sang sau'}). Resume() ', là nơi tôi nghĩ nó nên đi, tôi nhận được lỗi ** Sử dụng các minion định danh chưa được giải quyết **. Tôi dường như không thể hiểu được cách giải quyết! – ZbadhabitZ

+0

@ZbadhabitZ kiểm tra câu trả lời cập nhật của tôi –

+0

Làm cho tinh thần với tôi ngay bây giờ! Cảm ơn, @Andriy! – ZbadhabitZ

19

Tôi đã sửa lỗi bằng cách tạo trình xử lý hoàn tất. Bạn có thể thực hiện việc này thay vì sử dụng thông báo:

class func fetchMinionData(completionHandler: (minions: [Minion]) -> Void) { 

    var myURL = "http://myurl/test.json" 

    let dataURL = NSURL(string: myURL) 

    let request = NSURLRequest(URL: dataURL!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0) 

    let session = NSURLSession.sharedSession() 

    session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in 
     let minionJSON = JSON(data!) 

     var minions = [Minion]() 

     for (_, minionDictionary) in minionJSON { 
      minions.append(Minion(minionDetails: minionDictionary)) 
     } 

     completionHandler(minions: minions) 
     //THIS IS WHERE YOUR PREVIOUS ERROR OCCURRED 

    }).resume() 
} 
+2

chắc chắn cách giải quyết dễ nhất – joey

Các vấn đề liên quan