我很困惑。下面我发生了以下情况。
如您所见,我在打开之前检查userOfProfile是否为nil。但后来我在我的控制台中得到了以下内容。
致命错误:在解包可选值时意外发现nil
错误后我的堆栈跟踪中也会出现以下内容:
0x10f67b538 <+72>: leaq 0x4d1e1(%rip), %r8 ; partial apply forwarder for Swift.(_fatalErrorMessage (Swift.StaticString, Swift.StaticString, file : Swift.StaticString, line : Swift.UInt, flags : Swift.UInt32) -> Swift.Never).(closure #2)
0x10f67b53f <+79>: movq %r12, %rsi
0x10f67b542 <+82>: movq %r13, %rdx
0x10f67b545 <+85>: movl -0x2c(%rbp), %ecx
0x10f67b548 <+88>: movq %rax, %r9
0x10f67b54b <+91>: callq 0x10f54de60 ; function signature specialization <preserving fragile attribute, Arg[1] = [Closure Propagated : reabstraction thunk helper from @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> () to @callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> (@out ()), Argument Types : [@callee_owned (@unowned Swift.UnsafeBufferPointer<Swift.UInt8>) -> ()]> of generic specialization <preserving fragile attribute, ()> of Swift.StaticString.withUTF8Buffer <A> ((Swift.UnsafeBufferPointer<Swift.UInt8>) -> A) -> A
任何关于该怎么做的想法都将受到赞赏。我很困惑。
var userOfProfile:User?
func loadProfile(_ user: User){
self.userOfProfile = user
if self.userOfProfile != nil{
self.profileView.firstName = self.userOfProfile!.firstName
}else{
self.profileView.firstName = ""
}
...
}
...
//Init for the user object that was passed in.
let entityDescription = NSEntityDescription.entity(forEntityName: "User", in: self.managedObjectContext!)
let matchedUser = User(entity: entityDescription!, insertInto: nil)
matchedUser.parseRaw(matchDict)
...
class User: NSManagedObject {
@NSManaged var userId: String
@NSManaged var dbId: String
@NSManaged var aboutMe: String
@NSManaged var firstName: String
...
名字属性不是可选的。我甚至可以通过在控制台中执行po self.userOfProfile!.firstName
打印出firstName的值,并且它可以解析正常...
看,在调试器中解析得很好,在下一行崩溃。有没有搞错。
如果任何其他代码有帮助,请告诉我。
更新:问题是profileView为nil,因此设置profileView.firstName会导致崩溃。
我不明白为什么profileView为零。新建profileView的代码如下所示:
//Event that causes all this
let newProfile = ProfileViewController()
newProfile.matchedUserProfile = true
newProfile.matchedReportDelegate = self
newProfile.loadProfile(self.selectedUser!)
//Within ProfileViewController
override func viewDidLoad() {
super.viewDidLoad()
profileView = ProfileView(frame: self.view.frame)
self.view = profileView
在ProfileViewController的viewDidLoad中,创建了ProfileView。我已经跟踪了堆栈跟踪,并且在viewDidLoad之前调用了loadProfile。我该如何避免这种情况?我在代码中有许多其他位置,我执行此操作并且它不会崩溃(这几周之前并没有用于崩溃和我们的产品版本)
答案 0 :(得分:2)
如果firstName
的{{1}}属性是可选的,那么如果值为n并且您尝试强制解包该值,它将在运行时产生错误。所以,如果让我们构建安全解开,请使用。
userOfPrifile
<强>更新强>
我猜你的if let firstName = self.userOfProfile?.firstName {
self.profileView.firstName = firstName
} else {
self.profileView.firstName = ""
}
是零。请在运行时检查profileView
。
答案 1 :(得分:1)
首先检查nil,然后强制展开,你永远不应该展开选项。
使用条件绑定,这会检查并解开一个原子操作。:
if let user = self.userOfProfile {
self.profileView.firstName = user.firstName
}
else {
self.profileView.firstName = ""
}
在这种情况下,使用可选链接和 nil coalescence operator 更简洁:
self.profileView.firstName = self.userOfProfile?.firstName ?? ""
答案 2 :(得分:0)
在你的代码中,似乎第一个名称在userProfile中声明为隐式可选:
var firstName:String!
所以确保firstName在访问之前有价值,否则它会崩溃。
所以改为:
var firstName:String?
并像这样访问:
if self.userOfProfile != nil{
self.profileView.firstName = self.userOfProfile!.firstName ?? ""
}