SanDisk’ten iPhone Yedekleme ve Hızlı Şarj Çözümü: iXpand Base

Reklamlar

Swift @autoclosure Attribute

Swift AutoClosure

Bir fonksiyonun şayet “() -> T” türünde bir parametresi varsa, @autoclosure attribute (özniteliği) ile küme parantezi kullanılmadan çağırılabilir. Örneğin:

// Explicit Closure

func Test(parametre p: () -> Int)

{

print(p())

}

Test(parametre: {3 + 5}) // 8

Yerine aşağıdaki gibi kullanılabilir:

func Test(parametre p: @autoclosure () -> Int)

{

print(p())

}

Test(parametre: 3 + 5) // 8

Bu kod parçasında argüman otomatik olarak bir closure’a dönüşmektedir.

Swift4 type() fonksiyonu ile dinamik türün öğrenilmesi

Yakında çıkacak olan #Swift kitabımdan küçük alıntılara devam:

Swift’te bir nesnenin dinamik tür ismini öğrenmek için geçmiş versiyonlarda dynamicType kullanılmaktaydı ancak yeni versiyonda bu işlem için artık type() isimli fonksiyon kullanılmaktadır.

Bu fonksiyonun parametre etiket isminin “of” olması okuyucunun aklını karıştırıp, C türevi dillerdeki typeof() operatörününün Swift’te olduğu izlenimini uyandırmamalıdır. “obj” bir nesne örneği olmak üzere:

print(obj.dynamicType) // yerine
print(type(of: obj)) // kullanılmalıdır

Şüphesiz aynı işlem gerektiğinde self için de yapılabilir.

Swift Protocol Composition

Birden fazla protokol ile birleştirilmiş referanslar bildirilebilir. Bu durumda o referansa ancak o bildirimde belirtilen protokollerin hepsini destekleyen bir sınıf, yapı ya da enum değişkeni atanabilir.

Bildirimde protokol birleştirme işlemi protokol isimlerinin arasına “&” sembolü konularak yapılır. Örneğin:

protocol Protokol1

{

func Foo()

}

protocol Protokol2

{

func Bar()

}

class CSample1 : Protokol1

{

func Foo()

{

print(“foo”)

}

}

class CSample2 : Protokol1, Protokol2

{

func Foo()

{

print(“foo”)

}

func Bar()

{

print(“bar”)

}

}

/////////////TEST//////////////

func Test(prm: Protokol1 & Protokol2)

{

prm.Foo()

prm.Bar()

}

// Test(prm: CSample1())

// Argument type CSample1 doesnt conform to expected type ‘…’

Test(prm: CSample2()) // OK

Şüphesiz protokol listesinde sırasının bir önemi yoktur. Örneğin:

let p1: Protokol1 & Protokol2 = CSample2()

let p2: Protokol2 & Protokol1 = p1       // geçerli

Swift 3 Associated Type Generic Protocol typealias associatedtype

Dikkat: Aşağıdaki yazı yakında yazımı tamamlanacak olan Swift kitabımdan sınırlı bir alıntıdır izinsiz kopyalanıp kullanılamaz.

Swift’te fonksiyonların, class’ların, structure’ların ve enum’ların generic olabileceği daha önce de belirtilmişti. Ancak protokoller bu durumun bir istisnasıdır yani bir protokol generic olamaz. Bu nedenle aşağıdaki işlem “Protocols don’t allow generic parameters; use associated types instead” hatası ile sonuçlanır.

protocol PSample<T>

{

}

Hata mesajından da anlaşılabileceği gibi bu durumda uygulanması gereken çözüm; associated type kullanımıdır. Aşağıdaki örneği inceleyiniz:

protocol Repository

{

// Associated type tanımlamak

typealias Entity

// associatedtype Entity // Xcode 7.3+

func Save(e:Entity)

func Delete(e:Entity)

func GetRecord() -> Entity

func GetTable() -> [Entity]

}

Repository isimli protokol, temel veritabanı işlemlerini entity türünden bağımsız olarak soyutlamak için yazılmıştır. Burada typealias anahtar sözcüğü ile tanımlanan Entity aslında bir tür generic parametredir. Bu protokolü implemente eden özgün repository sınıfları hangi entity için yazılmışlarsa Entity yerine o sınıfı kullanabilir. Aşağıdaki örnekte Customer isimli sınıf Entity yerine geçecek olan sınıftır.

class Customer {

}

class CustomerRepository : Repository

{

func Save(e:Customer)

{

}

func Delete(e:Customer)

{

}

func GetRecord() -> Customer

{

return Customer()

}

 

func GetTable() -> [Customer]

{

return []

}

}

İpucu: typealias anahtar sözcüğünün iki farklı anlamda (türlere takma isim atamak ve associated type tanımlamak için) kullanılıyor olması bir tür karışıklığa neden olmaktaydı. Bu karışıklığı gidermek için Swift 3 versiyonunda associated type tanımlama amacıyla ile associatedtype isimli yeni bir anahtar sözcük gündeme getirildi. typealias anahtar sözcüğünün bu amaçla kullanımı Xcode 7.3 güncellemesi sonrasında bu gerekçeyle bir uyarıya neden olmaktadır.

Swift Generic & Contraint Kullanımı

Dikkat: Aşağıdaki yazı yakında çıkacak olan Swift kitabımdan bir alıntıdır izinsiz kopyalanıp kullanılamaz.

Swift’te generic bir fonksiyon ya da sınıfa herhangi bir türde açılım yapılabilir. Ancak geliştirici şayet isterse açılım yapılabilecek türlerde kısıtlamaya gidebilir. Kısıtlamalar, açılım yapılabilecek türlerin belirli bir taban sınıftan türetilmesi ya da belirli bir protokolü implemente etmesi şartına dayandırılabilir. Örneğin aşağıdaki Foo() isimli fonksiyonun ilk parametresine açılım yapacak olan türün CKisitlama isimli sınıftan türetilmesi, ikinci parametresi ise PKisitlama isimli protokolden implemente edilmesi gereklidir.

class CKisitlama {

}

class Sinif1 {

}

class Sinif2 : CKisitlama {

}

protocol PKisitlama {

}

class CSinif3 {

}

class CSinif4 : PKisitlama {

}

func Foo<A: CKisitlama, Z: PKisitlama>(p1:A, p2:Z)

{

}

////// TEST ///////

Foo(Sinif1(), p2: CSinif3()) // Geçersiz!!!

Foo(Sinif2(), p2: CSinif4())

Sinif1 ve Sinif3 türündeki nesneler gerekli şartları sağlamadıkları için A ve Z yer tutucuları için açılım yapamazlar.

where anahtar sözcüğü

Swift’te kısıtlamalar sadece generic fonksiyonlar için değil aynı zamanda generic türler için de belirtilebilir. Kısıtlamayı aşma koşulu ise yine belirli bir sınıftan türetme ya da belirli bir protokolü implemente etme şeklinde kurgulanır. Generic türün bildiriminde <> içerisinde yazılan yer tutucu(lar) için where anahtar sözcüğünden sonra bir veya daha fazla sayıda kısıtlama belirtilebilir. Örneğin aşağıdaki Controller isimli sınıfta T yerine PRepository ve PTestable protokollerini implemente eden bir tür kullanılabilir.

protocol PRepository

{

}

 

protocol PTestable

{

}

 

class CRepository1

{

}

 

class CRepository2 : PRepository

{

}

 

class CRepository3 : PRepository, PTestable

{

}

 

class Controller<T where T: PRepository, T: PTestable>

{

}

var cnt = Controller<CRepository3>()

Bu örnekte CRepository1 ve CRepository2 gerekli şartları sağlamadığı için açılım yapma amacıyla kullanılamayacak sınıflardır.

C-style for statement is deprecated and will be removed in a future version of Swift

İpucu : Konvansiyonel for döngüsü Swift’in 2+ versiyonlarında Xcode 7.3 güncellemesi sonrasında C-style for statement is deprecated and will be removed in a future version of Swift” açıklamalı bir uyarıya neden olmaktadır. Dahası konvansiyonel for döngüsü kullanımının gelecekteki Swift versiyonlarında tümüyle sona erdirileceği yönünde yaygın bir beklenti vardır. Bu nedenle for-in döngüsü daha çok önem arz etmektedir. Sadece dizi veya nesne koleksiyonlarının dolaşılması amacıyla değil konvansiyonel for döngüsü yerine de kullanılabilir. Örneğin:

for var i = 0; i <= 9; i += 1
{
 print("\(i)") // 0 – 9
}

yerine:
for var i in 0 ..< 10
{
    print("\(i)") // 0 – 9 
}