2016-04-10 12 views
-2

Özel bir hücreye sahip bir tablo görünümü var. Bir satır seçtikten sonra, bazı şeyler olacak. Satır seçildikten sonra başka şeyler de olacak."Bir İsteğe bağlı değeri çıkarılırken beklenmedik bir şekilde sıfır bulundu" DidDeselectRowAtIndexpath

Her şey yolunda, ancak düzeltemediğim bir hata var. Her istediğim satır ve 'hiçbir şey' olmuyor dokunabilirsiniz ama ardından son satır veya başka bir şekilde ikinci sıradaki dokunun ve eğer etrafta bu hatayı alıyorum:

unexpectedly found nil while unwrapping an Optional value

LLDB bana gösterdi nerede hata oluştu ve bu kod satırında olmalıdır: Bu sorunu çözmek için nasıl bilir herkes

let cell = tableView.cellForRowAtIndexPath(indexPath) as! TaskViewerCell 

var mı? Aşağıda her iki işlevin kodunu ekledim.

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! TaskViewerCell 

    number = indexPath.row 
    if cell.submit.hidden != false || next[0..<indexPath.row].contains(false){ 
     cell.submit.setTitle("Not completed", forState: .Normal) 
     cell.submit.setTitleColor(UIColor.orangeColor(), forState: .Normal) 
     logbook = "Pending" 
    }else{ 
     logbook = "completed" 
     cell.submit.setTitle("Completed", forState: .Normal) 
     cell.submit.setTitleColor(UIColor.greenColor(), forState: .Normal) 
    } 
    if indexPath.row != 0 && next[indexPath.row-1] == true{ 
    cell.nSwitch.enabled = true 
    cell.nSegment.enabled=true 
    cell.nButton.enabled = true 
    cell.submit.enabled = true 
     print("tapped\(indexPath.row)") 
    }else{ 
     cell.nSwitch.enabled = false 
     cell.nSegment.enabled=false 
     cell.nButton.enabled = false 
     cell.submit.enabled = false 
    } 

} 

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { 
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! TaskViewerCell // This is where is should go wrong!! 
    switch1[indexPath.row] = cell.nSwitch.on 
    yesno1[indexPath.row] = cell.nSegment.selectedSegmentIndex 
    if cell.nField != "" { 
      field1[indexPath.row] = cell.nField.text! 
      }else{ 
      field1[indexPath.row] = cell.nField.placeholder! 
     } 
    topField[indexPath.row] = cell.topField.text! 
    topSegment[indexPath.row] = cell.topSegment.selectedSegmentIndex 

    cell.nSwitch.enabled = false 
    cell.nSegment.enabled = false 
    cell.nButton.enabled = false 
    cell.submit.enabled = false 

} 
+1

Hatanın ne anlama geldiğini biliyorsanız, '!' Kullanmayı durdurun (ve gerçek türün ne olduğunu görmek için hata ayıklayıcısını kullanın) –

+0

Aşağıdaki yanıtlar açıklamanızı sağlar. Potansiyel 'nil' dönüşünü cellForRowAtIndexPath'den ele alıyor, ancak tablo hücrelerindeki durumu izlediğiniz için daha büyük bir sorununuz var. Veri modelinizde durumu izlemeniz gerekir. Hücreler ekranı kapatabilir ve daha sonra 'nil' hücresi – Paulw11

+0

ile karşılaştığınız zaman durum bilgisi kaybolacaktır. (Ne yapar?) Önemli bir hatanın olası kopyası: Beklenmedik şekilde sıfır bulundu, isteğe bağlı bir değer "ortalama?" (Http: //stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) – jtbandes

cevap

0

@ ryantxr'ın yanıtı doğrudur, ancak biraz farklı bir yaklaşım kullanırdım. Eğer "üzgün yolunu" konum kullanım guard kullanarak

override func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { 
    let untypedCell = tableView.cellForRowAtIndexPath(indexPath) 
    guard let cell = untypedCell as? TaskViewerCell else { 
     assertionFailure("CFRAIT returned nil or inappropriately typed cell: \(untypedCell)") 
     return 
    } 

    // action on the cell 
} 

hemen (yani, bir nil veya uygunsuz yazılan hücredir) ve daha sonra pyramid of doom yol açabilir (daha fazla girinti olmadan mutlu yoluna geçmeden).

assertionFailure hata ayıklama modunda kilitlenecek ve tam olarak nelerin yanlış gittiğini gösterecek, ancak hata ayıklama modunun dışında (yani App Store'da) atlanacak ve bir şey yapmadan güvenli bir şekilde geri döneceksiniz. Bu belirsiz davranışa sahip olmak yerine, preconditionFailure modelini kullanmak isteyebilirsiniz. Airspeed Velocity'den gelen This answer, iddialar ve önkoşullar hakkında daha fazla ayrıntıya giriyor.

Eğer bu muhafızı kodunuza eklerseniz, bunu onayladığını görmelisiniz. Hata ayıklayıcıda, untypedCell'un nil olup olmadığını veya yalnızca TaskViewerCell'dan başka bir tür olup olmadığına bakın. Bu, size hata ayıklamak için bir sonraki adımı verir.

+1

'cellForRowAtIndexPath' ifadesinin tam olarak geçerli olması durumunda geçersizdir. Bu hücre şu anda ekranda değil. OP, daha çok temel bir soruna sahiptir, çünkü veri modellerinden ziyade hücrelerde devleti tutmaya çalışmaktadırlar. Hücreler ekrandan hareket ettikçe, durum kaybolabilir. Bunu düzeltiyorlarsa muhtemelen bir didDeselect metoduna bile ihtiyaç duymazlar. – Paulw11

+0

Paul ne dedi. (oy) –

+0

Temel sorunun daha temel olduğu doğrudur, ancak Google aramaları sık sık buraya geldiğinden, yeniden mimariden ziyade, sorunun cevabını vermeye çalışıyorum. – wjl

0

Ünlem! Swift'de, isteğe bağlı olarak paketlenemediğinizden kesinlikle emin değilseniz neredeyse hiç kullanılmamalıdır. Durumunuzda, çağrı geri dönüyor.

if let cell = tableView.cellForRowAtIndexPath(indexPath) as? TaskViewerCell { 
    // it worked 
} 
else { 
    // it didn't work 
} 
0

teşekkür ederiz. Hücrelerin yeniden kullanılmasıyla ilgili bir şey yapmak zorunda olduğunu bilmiyordum (bu yöntemin sonunda düzelttiğini düşündüm). cevaplar yardımıyla bu işlevin (neredeyse) aynı didDeselectRowAtIndexPath olduğu gibi yapılacaktır ve seçilen hücre de seçilmemiş edilecektir yılında scrollViewWillBeginDragging

yardımıyla bu sorunu aşmak için bir çözüm yarattı. Şimdi, eğer en üste gitmek kaydırarak en üste gitmek istiyorsanız, değerler tekrar kullanılmadan önce kaydedilecektir. Belki bu da başkaları için bu sorunu çözebilir.

İlgili konular