2016-05-05 110 views
0

https://github.com/mateo951/ISBN-Vista-Jera-rquica- Github鏈接 我有的結構應該是在互聯網搜索後追加值。互聯網搜索在一個函數中調用並返回兩個字符串和一個圖像。當我嘗試追加結構中的返回值時,圖像被保存,但字符串爲零。函數返回指定的值但結構不附加其值

var datosLibros = [bookData]() 

@IBAction func Search(sender: UITextField) { 
    let (title1, author1, cover1) = (internetSearch(sender.text!)) 
    let libro = bookData(title: title1, author: author1,image:cover1) 
    datosLibros.append(libro) 
    print(datosLibros) 
} 

保存的結構被打印到控制檯如下:

bookData(title: "", author: "", image: <UIImage: 0x7f851a57fbf0>, {0, 0}) 

結構:

struct bookData { 
    var title: String 
    var author: String 
    var image: UIImage 
    init(title: String, author: String, image: UIImage) { 
     self.title = title 
     self.author = author 
     self.image = image 
} 

}

在先進的感謝所提供的幫助,任何建議。我是新來的,所以有很多東西被發現。

+0

在'internetSearch'功能,你實際上是預成型http請求? –

+0

不,我不這麼認爲..我用NSURL會話,然後與網址的數據任務..甚至認爲我已經檢查,值確實是在搜索後返回的功能,所以它不是連接或請求.. –

回答

0

問題不在於您發佈的代碼,而是與internetSearch

但是在我解釋那裏發生了什麼之前,只是簡單介紹一下Swift結構。結構帶有一個免費的初始化程序,該初始化程序將結構中定義的每個存儲屬性的參數作爲參數。參數標籤對應於變量標籤。

所以對你的結構bookData(這確實應該是BookData因爲類型應該是大寫),您不需要包括初始化你寫的,因爲它會爲你自動提供,只要你不產生任何額外BookData初始化。

現在你的結果不是你所期望的。您的String s不會作爲nil返回。相反,他們回到空的String s或「」。在Swift中,「」與nil非常不同,這意味着完全沒有價值。所以你的String確實在那裏,它們只是空的。

好的,我們的String已經空了。我們的形象如何?不,我們的形象也不會回來。您認爲這是因爲您看到控制檯中印有UIImage參考文獻,但如果您仔細觀察,您會發現它是一張虛假圖像。請注意實例的內存地址後面的「{0,0}」。據我所知,這意味着圖像的大小爲0 x 0.您知道多少有用圖像的大小爲0 x 0?

所以,現在我們發現我們的String已經空了,實際上我們的形象也是如此。這裏發生了什麼?

那麼,在你的實現internetSearch我在GitHub上找到,這是第一件事情,你做的事:

var bookTitle = String() 
var bookAuthor = String() 
var bookCover = UIImage() 

當然,你這樣做,讓你有準備撲通的正確類型的一些變量一些實際的結果,如果你找到他們。爲了好玩,讓我們來看看如果沒有結果,上面代碼的結果會是什麼。

那麼,initializer for String that accepts no parameters會產生一個空的String被創建。

好吧,我們的形象如何。雖然UIImage文件甚至沒有提及的初始化不帶參數,它也繼承了一個從NSObject和事實證明,它只是創建一個空的圖像對象。

所以我們現在已經發現了什麼internetSearch正在恢復實際上是一樣的,如果沒有結果會是怎樣。假設你正在尋找你知道存在的東西,那麼搜索邏輯肯定有問題,對吧?不必要。我注意到,您的internetSearch其餘的實現依賴於你使用像這樣的NSURLSession

var bookTitle = String() 
var bookAuthor = String() 
var bookCover = UIImage() 

let session = NSURLSession.sharedSession() 

let task = session.dataTaskWithURL(url) { (data, response, error) -> Void in 

// Lots of code that eventually sets the three variables above to a found result 

} 

task.resume() 

return (bookTitle, bookAuthor, bookCover) 

這似乎好得很,除了那NSURLSession異步執行任務的事實!是的,在某些情況下,你甚至可以發回主隊列來執行一些任務,但是閉包作爲一個整體是異步的。這意味着,只要您撥打task.resume()NSURLSession執行自己的線程/隊列/網絡上的任務,只要是任務設置它在完成前返回方式。所以task.resume()幾乎立即返回,在任務中的任何搜索代碼實際運行之前,特別是在它完成之前。

然後,運行時進入到下一行並返回這些三個變量,就像你告訴它。這當然是問題所在,因爲internetSearch函數在task有機會異步運行並將它們設置爲有用值之前正在返回那些初始空變量。

建議一個功能齊全的解決方案可能超出了這個已經很長的答案的範圍,但它需要對實現細節進行大的更改,並且應該搜索使用由NSURLSession返回的數據。

沒有我發佈任何代碼的一種可能的解決方案是讓你的internetSearch函數不返回任何東西,但是在任務調用完成後調用一個函數,然後將結果附加到數組並打印出來,就像顯示。請研究這個概念。

另外,我建議改變你的internetSearch實施進一步通過聲明的初始值不爲:

var bookTitle = String() 
var bookAuthor = String() 
var bookCover = UIImage() 

...但是:

var bookTitle: String? 
var bookAuthor: String? 
var bookCover: UIImage? 

這樣一來,如果你找到比你的結果可以表示它包裹在一個Optional和如果沒有可以表示爲nil,這將自動變量的默認值中的代碼的正上方。

+0

謝謝馬修!我真的很感激時間和耐心來解釋每一個細節,甚至更進一步,試圖瞭解其可能的錯誤。你已經清除了近6個月的「經驗」的疑慮。我會考慮你的建議,希望我能得到這個代碼的功能。再次感謝! –

+0

不客氣。很高興我能幫上忙! –

+0

好消息馬修!我成功地設法使該功能工作,現在它返回適當的值。我消除了會話,並嘗試用do-catch塊!再次感謝... –