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.

Reklamlar

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.

Android ConstraintLayout

Aşağıdaki yazı Android Programlama Eğitimi kitabımın 3. baskısından bir alıntı olup izinsiz kopyalanamaz.

ConstraintLayout, Google I/O 2016 etkinliğinde tanıtılan yeni özelliklerden belki de en dikkate değer olanı. Zira bu layout nesnesi ile görsel tasarım hem daha kolay geliyor, hem de ezeli rakip iOS’tan ironik bir alıntı yapılmış oluyor. ConstraintLayout, özellikle RelativeLayout ile yaşanan bazı sorunlara çare olabilmesi amacıyla düşünülmüş. Örneğin yüzdelik değerlerin verilebilmesi ve iç içe (nested) layout kullanımı nedeniyle oluşan karmaşıklığın azaltılması gibi. Unbundled bir kütüphane olması nedeniyle de API-9‘a kadar geriye uyumlu yani çok eski versiyonlarda bile kullanılabilecek özellik.

Dikkat: Bu özelliğin kullanımı Android Studio 2.2 gerektirmektedir. Bu başlık, kitabın 3. baskısının yazıldığı günlerde Android Studio 2.2 preview2 versiyonu ile hazırlanmıştır. Dolayısıyla gerçek sürümde olası bir takım değişiklikler gündeme gelebilir. Bu gerekçeyle konuya başlangıç seviyesinde değinilmiştir.

Bu layout üzerine paletten herhangi bir UI elemanı (örneğin buton) sürüklenip bırakıldığında henüz hiç bir constraint’e (kısıtlamaya) sahip olmayacaktır. Constraint oluşturmak için “buton seçili durumdayken” etrafındaki küçük yuvarlaklardan herhangi bir yöne sürükle-bırak işlemi yapılırsa örneğin (activity’nin üst kenarına) bir constraint otomatik olarak oluşur.

android-contraint1

Aşağıdaki kod bu yöntemle oluşturulmuş butona ait üç farklı constraint’i göstermektedir. Activity’nin üst, alt ve sol kenarına göre butona constraint’ler eklenmiştir. CheckBox’ın ise üst kenarı activity’e göre alt kenarı ise butona göre konumlandırılmıştır.

 

<?xml version=”1.0″ encoding=”utf-8″?>
<android.support.constraint.ConstraintLayout       xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
xmlns:app=”http://schemas.android.com/apk/res-auto&#8221;
xmlns:tools=”http://schemas.android.com/tools&#8221;
android:id=”@+id/act”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
tools:context=”org.android.dernegi.MainActivity”>

<Button       android:id=”@+id/btn”
android:text=”Deneme”
android:layout_width=”100dp”
android:layout_height=”80dp”
android:backgroundTint=”#ec0404″
android:layout_marginStart=”96dp”
android:layout_marginTop=”120dp”
android:layout_marginBottom=”16dp”
app:layout_constraintVertical_bias=”0.66″        app:layout_constraintLeft_toLeftOf=”@+id/ç”
app:layout_constraintTop_toTopOf=”@+id/act ”       app:layout_constraintBottom_toBottomOf=”@+id/act ”   />    <CheckBox
android:text=”CheckBox”
android:layout_width=”136dp”
android:layout_height=”46dp”       android:layout_marginTop=”16dp”
android:layout_marginBottom=”8dp”      tools:layout_editor_absoluteX=”208dp”
android:id=”@+id/chk”
app:layout_constraintTop_toTopOf=”@+id/act”
app:layout_constraintBottom_toTopOf=”@+id/btn”
/>
</android.support.constraint.ConstraintLayout>

android-contarint-2

Araç çubuğuna at detaylara değinmek gerekirse U mıknatıs işaretli düğme; autoconnect özelliğine aktif/pasif hale getirmekte. X işaretli düğme; oluşturulmuş constraint’leri silmekte, ampul işaretli düğme ise seçili elemanın editördeki konumuna göre constraint’leri otomatik olarak eklemektedir.

WindowsPhone FM Radio

Windows Phone’un ilginç özelliklerinden birisi de bu. Android ve iOS ‘ta olmayan bu özellik Windows Phone’ların donanımsal olarak aynı zamanda bir radyo alıcısına sahip olması. İşte programatik olarak kullanımı:

FMRadio rd = FMRadio.Instance;
rd.PowerMode = RadioPowerMode.On;
rd.Frequency = 90.8;
rd.CurrentRegion = RadioRegion.Europe;

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.

Swift Delegation Pattern

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

Bu patern bir nesnenin yerine getirmesi gereken bir görevi kendisi yapmak yerine başka bir nesneye -delege ederek- görevi delege ettiği nesneye yaptırmasını tematize eder. Başka bir deyişle, nesne söz konusu görevi farklı bir nesnenin yardımıyla gerçekleştirir.

Bu patern’in implementasyonunda anahtar nokta delege eden ve edilenin aynı protokolü (interface’i) desteklemesidir. Ayrıca delege eden bu protokol türünde bir nesne referansı (property) içermelidir. Bu sayede o property’e atanacak olan nesneye görev delege edilmiş olur.

swift delegation patern uml diagram

swift delegation patern uml diagram

Şekil 6.1’deki UML diyagramında görülen C sınıfı, Task() isimli fonksiyonla sembolize edilen görevi A veya B’den yardım alarak (A veya B türündeki bir nesneye delege ederek) gerçekleştirecektir. Bu karar, ToDelegation() isimli fonksiyona gönderilen parametrenin polimorfik şekildeki kullanımına dayandırılmıştır. Yani ToDelegation() isimli fonksiyona A veya B türünde bir nesne parametre olarak geçilmekte ve görev o nesneye delege edilmektedir.

protocol Delegation

{

func Task()

}

class A : Delegation

{

func Task()

{

print(“Görevi A nesnesi gerçekleştirdi”)

}

}

class B : Delegation

{

func Task()

{

print(“Görevi B nesnesi gerçekleştirdi”)

}

}

class C : Delegation

{

var delegate:Delegation?

func ToDelegation(delegate:Delegation)

{

self.delegate = delegate

}

func Task()

{

self.delegate!.Task()

}

}

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

var c = C()

// A’ya delege et

c.ToDelegation(A())

c.Task()

// B’ye delege et

c.ToDelegation(B())

c.Task()

Çıktı:

Görevi A nesnesi gerçekleştirdi

Görevi B nesnesi gerçekleştirdi