我是Swift / iOS的新手,所以请耐心等待:
我正在尝试从另一个类访问一个类中的函数,并更新UIImage名称。
在我的viewcontroller类中,我有
class Documents: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var UpdateImage: UIImageView
override func viewDidLoad() {
super.viewDidLoad()
UpdateImage()
}
func UpdateImage() {
UpdateImage.image = UIImage(named: "NewImage")
}
}
一切正常,图像更新为" NewImage"
问题:我可以从另一个类访问UpdateImage函数,但是为什么在尝试更改Documents类中的图像时会产生错误?
class GetChanges {
var success = { operation:AFHTTPRequestOperation!, response:AnyObject!) -> Void in
var MakeChange = Documents()
MakeChange.UpdateImage()
}
}
这会在" UpdateImage.image = UIImage上生成错误(命名为:" NewImage")"在文件类中; "致命错误:在展开可选值"
时意外发现nil答案 0 :(得分:5)
当你在类本身中调用它时,它在自身上运行并且它已经从一个nib / storyboard创建。这意味着UpdateImage
存在。
当您从另一个类调用该方法时,当您调用此行时:
var MakeChange = Documents()
您正在创建Documents
的新实例。这不是通过nib / storyboard初始化的,因此它从不填充IBOutlet
值UpdateImage
。由于此值不存在,因此意外地找到nil
并引发错误。
您需要以某种方式保留对您尝试显示的Documents
实例的引用。我需要更多信息来告诉你如何做到这一点。
另外,因为你提到你是新手,所以我想指出一些我注意到你的代码会让你很难阅读的问题。
为Types
变量名称保留大写的名称应该(几乎)从不以大写字母开头。
变量名称应反映它们所代表的对象。 UpdateImage
听起来像是一张图片。最好将此名称命名为updateImageView
函数也应该是小写的。以这种方式看大写是很奇怪的,并使代码看起来有点不舒服。
答案 1 :(得分:0)
了解View Contoller的生命周期,这对iOS开发人员来说是非常重要的知识。
正如洛根所说:
您正在创建一个新的文档实例。这不是通过nib / storyboard初始化的,因此它从未填充IBOutlet值UpdateImage
这意味着在调用ViewController init
之后(即Documents()
)nib
未加载。您只能在viewDidLoad
阶段之后在另一个代码中使用viewController的出口。 Apple docs:
您指定的nib文件不会立即加载。它是在第一次访问视图控制器视图时加载的。如果要在加载nib文件后执行其他初始化,请覆盖viewDidLoad()方法并在那里执行任务。
您可以删除MakeChange.UpdateImage()
,因为它会在viewDidLoad
中调用。或者,如果您想要传递特定的图像名称来查看控制器:
class Documents: UIViewController, UITableViewDataSource,
UITableViewDelegate {
@IBOutlet var UpdateImage: UIImageView
var imageName: String?
override func viewDidLoad() {
super.viewDidLoad()
updateImageView()
}
func updateImageView() {
if let imageName = imageName {
UpdateImage.image = UIImage(named: imageName)
}
}
}
之后,您可以使用
let documentsViewController = Documents
documentsViewController.imageName = "newImage"
当您加载documentsViewController时,将显示newImage