2014-09-30 21 views
39

Öyleyse sahip olmak istediğim bir işlevde bir kapanma elde edebilen bir sınıf, aynı zamanda bir noktada bu kapatmayı göz ardı etmek isteyebilir. Kapatma değişkeninin ayarlanmış olup olmadığını nasıl kontrol edebilirim ve işim bittiğinde onu silebilir miyim?İsteğe bağlı kapatma ve null olup olmadığını kontrol edin

türünde bir argüman listesi ile '=!' Çağırmak olamaz '(@lvalue (başarıların yanında: Bool !, ürünleri:! [AnyObject]) ->() ?, NilLiteralConvertible)' Type '(başarıların yanında : Bool !, ürünler: [AnyObject]!) ->()? ' protokole 'NilLiteralConvertible'

class someClass{ 
    //typealias completionHandlerClosureType = (sucsess:Bool!, items:[AnyObject]!)->() 
    var completionHandler:(sucsess:Bool!, items:[AnyObject]!)->()? 
    var hitpoints = 100 
    var someset = ["oh no!","avenge me!"] 
    init(){} 

    func getHitFunc(impact:Int, passedCompletionsHandler:(sucsess:Bool!, items:[AnyObject]!)->()){ 
     completionHandler = passedCompletionsHandler 
     hitpoints = hitpoints - impact 
    } 

    func checkIfDead{ 
     if hitpoints<=0 {    // The error received 
      if completionHandler != nil{// Cannot invoke '!=' with an argument list of type 
             //'(@lvalue (sucsess: Bool!, products: [AnyObject]!) ->()?, NilLiteralConvertible)' 
       //run the handler if dead 
       completionHandler(sucsess: true, items: someset) 
       //do not run it again 
       completionHandler = nil  //Type '(sucsess: Bool!, products: [AnyObject]!) ->()?' does not conform to protocol 'NilLiteralConvertible' 
      } 
     } 
     else{ 
      completionHandler = nil  //Type '(sucsess: Bool!, products: [AnyObject]!) ->()?' does not conform to protocol 'NilLiteralConvertible' 
     } 
    } 
} 

cevap

38

uymuyor Sen kapatma kendisi isteğe bağlı hale getirmek için parantez içinde kapatma imza sarmak gerekir. Şimdi yazıldığı şekilde, kapanma isteğe bağlı bir Boşluk (gerçekten anlam ifade etmiyor) verir. senin örneğin koduna

var completionHandler: ((sucsess:Bool!, items:[AnyObject]!)->())? 

Bazı stil noktaları ve revizyonlar:

// Capitalize class names so it's clear what's a class 
class SomeClass { 
    // "success" has two "c"s 
    var completionHandler: ((success:Bool!, items:[AnyObject]!)->())? 
    var hitpoints = 100 
    var someset = ["oh no!","avenge me!"] 

    init() { } 

    func getHitFunc(impact:Int, passedCompletionsHandler:(success:Bool!, items:[AnyObject]!)->()){ 
     completionHandler = passedCompletionsHandler 
     hitpoints = hitpoints - impact 
    } 

    // You were missing the argument list here: 
    func checkIfDead() { 
     if hitpoints <= 0 { 

      // Rather than checking to see if the completion handler exists, you can 
      // just call it using optional syntax like this: 
      completionHandler?(success: true, items: someset) 
     } 
     completionHandler = nil 
    } 
} 
39

Birincisi, tamamlama işleyicisi hakkında açıklama, parantez kullanımı ile isteğe bağlı her şeyi beyan etmek gerekir:

Ayrıca
var completionHandler: ((_ success: Bool, _ items: [Any]?) ->())? 

, not, sana kapatma varsa çünkü opsiyonel Bool (sen muhtemelen her zaman birgeçmesi yapmak anlamına sanmıyorumdeğeri, true veya false). Açıkça, items dizisi isteğe bağlı olabilir. Bittiğinde

Neyse

, sadece o isteğe unwrap emin olur:

func checkIfDead() { 
    if hitpoints <= 0 { 
     completionHandler?(true, items) 
    } 
    completionHandler = nil 
} 

Bu kapatma gerçekleştirir ve eğer o nil olsaydı açıkça kontrol etme ihtiyacı kaçınarak değil nil, yalnızca . Ne olursa olsun, bu typealias bu daha az kafa karıştırıcı hale getirebileceğini dava olabilir İçin


:

typealias CompletionHandlerClosureType = (_ success: Bool, _ items: [Any]?) ->() 

Sonra özellik basitçe:

var completionHandler: CompletionHandlerClosureType? 

alır işlevi İsteğe bağlı bir parametre olarak bu completionHandler yapabilir:

func startSomeProcess(passedCompletionHandler: CompletionHandlerClosureType?) { 
    completionHandler = passedCompletionHandler 
    // do whatever else you want 
} 

ve sonra nihai tamamlama mantığı değişmedi: Eğer Swift 2 yorumlamalar görmek istiyorsanız yukarıdaki Swift 3. için modifiye edilmiş

func finishSomeProcess() { 
    completionHandler?(true, items) 
    completionHandler = nil 
} 

(Not

, bu cevabın previous revision bakınız.

+0

tür takma adı mükemmel çözümdür – Yitzchak

İlgili konular