2014-09-16 70 views
5

üzerinde başarılı bir şekilde değerlendirirseniz, Field adlı bir özel nesnem var. Temel olarak bir formdaki tek bir alanı tanımlamak için kullanırım. İsteğe bağlı (nil)

class Field { 

    var name: String 
    var value: Any? 

    // initializers here... 
} 

kullanıcı formu gönderdiğinde

, ben bunların geçerli değerleri içeren emin olmak için Field nesnelerin her biri doğrulamak. Bazı alanlar böylece gerekli değildir Bazen kasten böyle value özelliğine nil ayarlayın:

field.value = nil 

ı kullandığınızda bu bir sorun teşkil görünüyor bir alan sıfır olup olmadığını belirlemek için izin verirsen-.

if let value = field.value { 
    // The field has a value, ignore it... 
} else { 
    // Add field.name to the missing fields array. Later, show the 
    // missing fields in a dialog. 
} 

ben kesme noktası ayarlamak field.value kasten nil ayarlı edildiğinde, öyle değil else if-let bloğun geçer else-if ve yukarıda. Ancak, field.value Başlatılmamış ve atanmamış bırakılan alanlar için, program diğer bloğa gider.

ben izin verirsem-bloğunun içinde field.value ve value çıktısını çalıştı:

if let value = field.value { 
    NSLog("field.value: \(field.value), value: \(value)") 
} 

Ve bu elde ediyoruz:

field.value: İsteğe bağlı (nil), değeri: nil

Bu yüzden, isteğe bağlı olarak, başlatılmamış olmanın ve diğerinin de sıfır. Ancak eğer if-let'in içinde bir tane bile ekleyecekseniz, derleyiciyi mutlu etmeyiz:

if let value = field.value { 
    if value == nil { // Cannot invoke '==' with an argument list of type '(Any, NilLiteralConvertible)' 
    } 
} 

Bunu nasıl aşarım? Sadece field.value'un nil olup olmadığını kontrol etmek istiyorum.

+1

Yeniden üretilemiyor. Hangi Xcode sürümünü kullanıyorsunuz? –

+0

Xcode 6 GM. Yeniden başlatmayı denedi, hala şans yok. :( –

+0

Sorunu gösteren eksiksiz bir kendi kendine örnek gönderebilir misin? –

cevap

3

Bunun nedeni, Any?'un Optional bir enum olduğu için herhangi bir değere izin verdiği ve Optional.None'un başka bir değer olarak yorumlandığından eminim!

AnyObject? sadece değeri Optional.None ile söz Optional.Some(Optional) izin vermez Optional.Some([any class object]) içerebilir bunun beri bunu yapmak mümkün olmalıdır.

Bu konu hakkında konuşmak bile çok kafa karıştırıcı. Nokta şudur: Any? yerine AnyObject?'u deneyin ve işe yarayıp yaramadığını görün. Matt'in yorumun noktasına


Daha bir o Any kullanmak istediği nedeni metin girişi için alan veya Çekirdek Veri nesneyi seçmek için amaçlanan bir alan ya olabilecek bir seçim için olduğunu bahseder.

Bu durumda yapılması gereken Swifty, enum with associated values, temel olarak tagged/discriminated union ile aynı şeydir.Burada beyan atamak ve böyle bir enum nasıl kullanılacağı açıklanmıştır: Böyle Bir enum kullanarak

enum DataSelection { 
    case CoreDataObject(NSManagedObject) 
    case StringField(String) 
} 

var selection : DataSelection? 

selection = .CoreDataObject(someManagedObject) 

if let sel = selection { // if there's a selection at all 
    switch sel { 
     case .CoreDataObject(let coreDataObj): 
      // do what you will with coreDataObj 
     case .StringField(let string): 
      // do what you will with string 
    } 
} 

işler bu Any? içine saklanıyor olabilir hangi dert etmeye gerek yoktur. İki durum var ve belgelendi. Ve elbette, seçim değişkeni herhangi bir endişe olmadan isteğe bağlı olabilir.

+1

Doğru cevap" kaçının " tüm maliyetler. Eğer isteğe bağlı 'Any' kullanıyorsanız, siz de berbatsınız. – Sulthan

+2

Evet, çünkü dil seçeneğinin 'İsteğe bağlı olan' Hiçbiri 'gerçek değer olarak kullanılmak üzere tasarlanması veya isteğe bağlı' Herhangi'da 'bir değerin bulunmadığını işaretlemek arasında bir yol olduğu görünmüyor. – Jesper

0

Any? türümü enum ile değiştirmenin bir ipucu var ama bu hatayı kafamdan çıkaramadım. Benim yaklaşımımı değiştirmek benim mevcut olanla ilgili bir şeyin yanlış olduğunu değiştirmiyor ve ben bir Optional(nil) çıkışına nasıl ulaştığımı anladım.

Yeni bir tek görünüm projesinde aşağıdaki görüntü denetleyicisini yazarak hatayı yeniden üretebildim. init imzasına dikkat edin. Kısaca

import UIKit 

class Field { 
    var name: String = "Name" 
    var value: Any? 

    init(_ name: String, _ value: Any) { 
     self.name = name 
     self.value = value 
    } 
} 

class AppState { 
    var currentValue: Field? 
} 

class ViewController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     let f = Field("Amount", AppState().currentValue) 
     NSLog("\(f.value)") 

    } 
} 

, I Any kabul eder ve ile tipi Any? bir özelliğine atar bir başlatıcı için bir sıfır değeri (AppState().currentValue) geçiyordu. Yolun bir yerinde Swift dolayısıyla Optional(nil), opsiyonel içinde AppState().currentValue arasında nil değerini sarar görünüyor

let f = Field("Amount", nil) // Type 'Any' does not conform to protocol 'NilLiteralConvertible' 

: burada komik şey yerine doğrudan nil geçtiyseniz, derleyici şikayet olacaktır.

+0

'nil' bir değer olarak (yalnızca bir anahtar kelime olarak) mevcut değildir, ancak 'İsteğe Bağlı' Hayır 'isteğe bağlı değişkenlerin varsayılan değeridir ve kendisini tanımlaması istendiğinde' sıfır 'yazdırır. – Jesper