2015-08-06 28 views
6

Uygulamamın farklı bölümlerinde yararlı olan bazı işlevleri/yöntemleri eklemek için Helper.swift dosyasını oluşturmak istiyorum.Bir işlev mi yoksa tip yöntemi mi kullanıyorsunuz?

En iyi uygulama hangisinin olduğunu merak ediyordum (eğer varsa): bir sınıf oluşturmak ve sadece tip yöntemleri oluşturmak veya sadece işlevler oluşturmak?

+0

Sanırım sınıf işlevi olarak kullanmalısınız. –

cevap

4

Yardımcı yöntemlerinize bağlam sağlamak ve genel ad alanını kirletmekten kaçınmak için genellikle uygun şekilde adlandırılmış türde bir yöntem kullanma eğiliminde olurdum. Benim kodu içinde grupla ilgili sabitler için oldukça liberal benim üst düzey türlerinde statik sabitleri ile

struct Helper { 
    static func helpfulMethod() { ... } 
} 

Ben de gömülü kullanın yapılar: Swift ise

, yapılar yapının bu tür için ideal bir aday vardır. özel Swift türlerini yazarken

, genellikle ilk kullanarak.Gerçeği düşünün ve kalıtım, referans semantik (değer semantik ile örtülü kopyalama aksine) veya sahiplik semantik (unowned/weak) gerekli olduğunda sadece sınıflara başvurmak gerekir. Bu durumda, yardımcı fonksiyonlarınız vatansız olacaktır ve konuşacak herhangi bir kalıtım yoktur, bu yüzden bir sınıf üzerinde bir yapının gerçekten tercih edilmesi gerekir.

Genel olarak, Swift dilinin, türler (ve protokoller/jenerikler) tarafından sağlanan örtük ad alanı lehine, global işlevlerden uzaklaştığını iddia ediyorum. Ama yine de büyük ölçüde bir tarz/kişisel tercih meselesi ve bir fayda fonksiyonu kadar basit bir şey için çok az sonuç veriyor.

0

Çözüm # 1:

class Helper { 
    class func classMethod() { 
     // TODO: play something 
    } 
} 

Ve diyoruz:

Helper.classMethod() 

Elma doc olarak:

onlar kodunuzda etrafında geçirildiğinde Yapılar hep kopyalandığı ve referans sayımı kullanmayın.

Çözüm # 2:

struct Helper { 
    static func classMethod() { 
     // TODO: do something 
    } 
} 

Ve kullanmak:

Helper.classMethod() 

bence çözüm 2. daha iyi çözüm 1. referans sayımı artırmaz çünkü .

GÜNCELLENMİŞ: playground ile test ettim. Aşağıdaki sonuca bakınız:

enter image description here Bu yardımcı olur umarız!

+0

tamam ama daha iyi olan nedir? Func classMethod() { // TODO: bir şey çal } '? – Nico

+0

Bir "örnek yöntemi" oluşturduğunuzda yardımcı yöntem ile gerçekten gerekli değildir. –

0

En iyi uygulama olup olmadığını bilmiyorum ama işte nasıl yaptığım.

Önce Bir protokolü:

protocol UtilityType { } 

Sonra (UIViewController için örneğin bir yardımcı fonksiyonu) genişletmek

extension UtilityType where Self: UIViewController { 
    func setDefaultTitleAttributes() { 
     navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.whiteColor()] 
    } 
} 

ve bu

class MyViewController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     setDefaultTitleAttributes() 
    } 
} 

extension MyViewController: UtilityType {} 
+0

Protokollerin uzantıları, yanılmıyorsam yalnızca Swift 2'de çalışır. – Nico

1

gibi kullanmak Bir sınıf veya bir yapı oluşturmak gerekli değildir. İşlevleri doğrudan Helper.swift dosyasına koyabilirsiniz. Ve bu dosyayı içe aktarma ifadeleri yazarak almanıza bile gerek yok.

Bunu test etmek için helper.swift adında bir dosya oluşturun ve dosyaya aşağıdaki kod satırlarını ekleyin. Sınıf veya yapı gerekmez.

import Foundation 

func addTwo(x: Int) { 
    return x+2 
} 

sadece gerekli argümanlarla işlevi çağıran başka dosyada bu işlevi kullanın. Sonra işlevini çağırdığınızda bir sınıf/yapı örneğinde aramak yok çünkü

let a = addTwo(9) 

Ben bu yöntemi tercih ediyorum. İkinci olarak, her bir işlevi bir sınıf işlevi veya statik bir işlev yapmak zorunda olmadığınız için daha temiz bir koda yol açar.

+1

Sanırım, @Nico bunun bir seçenek olduğunu anladı, ancak her yaklaşımın (küresel işlev ve tip yöntemi) yararları hakkında bir tartışma arıyordu. Bu, son paragrafınızdan uzaklaşmamaktır, ancak, bu yaklaşımın faydalarını tartıştığınız zaman :). – Stuart

+0

@Stuart Bu cevabı ekledim, ayrıca bunun bir olasılık olduğunu da belirtmek isterim. Ve bu yaklaşımın yararı daha az koddur. –

+0

Evet, gerçekten sabit bir şekilde yaptığım buydu. Oluşturduğunuz dosyada daha hızlı yazmak ve belki daha net olmak için daha hızlıdır, ancak @Stuart'ın bir bağlam sağlamasıyla ilgili cevabına katılıyorum. Ve aslında, yöntemin/sabitin adını hatırlamadığım zaman bana yardımcı olabileceğinin farkındayım, ancak bağlamı (veya bu durumda sınıf) yapmıyorum – Nico

1

Tip yöntemini tercih ederim çünkü bu sayede yöntemlerinizi kolayca ayırt edebilirsiniz.

Bazı yöntemlerin amaca yönelik tasarlandığı 50 ila 60 yönteme sahip olduğunuzu varsayalım, bazı yöntemler hesaplama amaçlıdır ve bazı yöntemler sunucuda veri almak ve göndermek içindir.

Bu senaryoda, tüm bu yöntemleri global olarak oluşturursanız, tanımak ve hatırlamak zorlaşacaktır. amacı DesignHelper sınıf/yapı yapmak ve class/static method

  • Yöntemleri olarak içine tüm bu yöntemleri koymak Tasarımı için kullanımıdır

    • Yöntemleri: Aşağıda gibi bazı sınıf/yapı içinde bu yöntemlerin birbirinden Şimdi eğer

      hesaplama amacıyla kullanmak için bir MathHelper sınıf/yapısını yapın ve tüm bu yöntemi class/static method

    • olarak kullanın. Proses verileri için sunucu ile kullanılacak yöntemleri kullanın ConnectionHelper sınıf/yapı ve tüm Kolayca yöntemin herhangi öğrenebilirsiniz ve aynı zamanda auto completion yardımcı olacaktır bu şekilde kullanarak class/static method

    olarak içine ese yöntemi.

    Teşekkür ederiz.

  • 1

    Sınıf fonksiyonları tek bir sınıf çalışmasıyla yapılır, ancak genellikle uygulamanızın genelinde kullanılan işlevler aynı nesneler üzerinde yeniden yayınlanır. Daha temiz bir yöntem, işlevinizi kullanacak nesnenin uzantılarında işlevlerinizi tanımlamaktır. Tüm uzantılarınızı Helper.swift

    adresinde bulabilirsiniz.Bu page.backgroundColor = UIColor.randomColor()

    gibi kullanımı ile

    extension UIColor 
    { 
        class func randomColor() -> UIColor 
        { 
         var randomRed:CGFloat = CGFloat(drand48()) 
         var randomGreen:CGFloat = CGFloat(drand48()) 
         var randomBlue:CGFloat = CGFloat(drand48()) 
    
         return UIColor(red: randomRed, green: randomGreen, blue: randomBlue, alpha: 1.0) 
        } 
    } 
    

    Demek hala kullanıma bağlı olarak sınıf fonksiyonları veya nesne fonksiyonları gibi işlevleri tanımlamak, ancak nesnenin uzantısı içinde olabilir.

    Bu, kodunuzu açık tutar, böylece çağrılarınızı kod tabanınızdaki yardımcılar aracılığıyla yönlendirmezsiniz. Fonksiyona ihtiyaç duyacağı nesne için açıkça tanımlanmıştır. Genişletilmiş bir işlevde anlam ifade etmeyen bir kod bulursanız, işlev muhtemelen daha odaklanmış bir işlevselliğe yeniden odaklanmaya ihtiyaç duyar.

    İlgili konular