函数返回指定的值但结构不会附加其值

时间:2016-05-05 21:48:23

标签: swift

https://github.com/mateo951/ISBN-Vista-Jera-rquica- Github Link 我有的结构应该是在互联网搜索后附加值。在函数内调用互联网搜索并返回两个字符串和一个图像。当我尝试在结构中追加返回的值时,图像被保存但字符串为零。

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
}

}

感谢您提供任何有关帮助的建议。我是新手,因此有很多东西被发现。

1 个答案:

答案 0 :(得分:0)

问题不在于您发布的代码,而是internetSearch

但是在我解释那里发生了什么之前,只需要快速了解Swift结构。结构带有一个自由初始值设定项,它将结构中定义的每个存储属性的值作为其参数。参数标签对应于变量标签。

因此,对于你的结构bookData(因为类型应该大写,它应该是BookData),你不需要包含你编写的初始化程序,因为它会自动为你提供,只要您不会创建任何其他BookData初始值设定项。

现在您的结果不是您所期望的。您的String不会以nil的形式返回。相反,它们会以空String或“”返回。在Swift中,“”与nil非常不同,这意味着完全没有值。所以你的String确实存在,它们只是空的。

好的,我们的String空无一人。我们的形象怎么样?不,我们的形象也没有回来。您以为是因为您在控制台中看到了UIImage参考文件,但如果您仔细观察,您会发现它是一张伪造的图像。注意实例的内存地址后面的“{0,0}”。据我所知,这意味着图像的大小为0 x 0.您知道有多少有用图像的大小为0 x 0?

所以现在我们发现我们的String空无一人,我们的形象也是如此。这是怎么回事?

好吧,在我在GitHub上发现的internetSearch的实现中,这是你做的第一件事:

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函数不返回任何内容,但在完成任务时调用一个函数,然后将结果附加到数组并打印出来,喜欢你表现出来。请研究这个概念。

此外,我建议您将初始值声明为:{/ p>,以进一步更改internetSearch的实施方式。

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

......但是:

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

这样,如果你发现一个结果而不是你可以表示它包含在Optional中,如果没有,你可以将其表示为nil,这将自动成为变量的默认值。代码直接在上面。