Optionals

Bir değerin herhangi bir bilgi bulundurmadığı durumları yöneten “Optionals” kavramı ile tanışacaksınız.

Mentorluk

Randevu OluşturKredi Al

Optional Nedir ?

Bir çok yazılım dilini birbirinden farklı kılan bir yan bulunur. Swift dilini diğer dillerden eşsiz kılan özelliklerden biri de “Optional” kavramı. Swift dilinde değişken ve sabitler optional olarak tanımlanabilir.

Optional Kavramına Neden İhtiyaç Duyarız ?

Swift dilinde sabit ve değişkenleri optional olarak tanımlayabileceğimizden bahsettik. Eğer yaptığınız uygulama internet bağlantısı ile etkileşime giriyorsa mutlaka optional tanımlama yapılmalıdır. Çünkü internetten veri gelip gelmeyeceğini bilemeyiz.

Daha Basit Bir Dil ile Anlayalım

Örnek 1 — Önümüzde bir kutu var. Bu kutunun içini doldurabileceğimiz gibi boş da bırakabiliriz. Bu tamamen bizim seçimimizdir.
Örnek 2 — Bize bir kutu getirildi. Bu kutunun içi boş ya da dolu olabilir. Bu tamamen karşı tarafın seçimidir.

Optional(?) durumu

Değişkenlerimizi aşağıdaki gibi tanımlayalım.

    
    var isim: String = "Ufuk"
    var ikinciIsim: String? = "Hüseyin"
    var soyIsim: String = "Köşker"
    

Bu değişkenlerin değerlerinin ‘nil’ yani boş olduğu durumda verdiği tepkiye bakalım:

isim ve soyIsim değişkenlerinin nil olma durumlarında Xcode bize kızdı 😃 Peki Neden ?
isim ve soyIsim değişkenlerinin veri türlerinin yanında (?) işareti bulunmuyor. Bu yüzden ‘Optional’ değildir. Bir başka deyişle mutlaka bir değeri olmak zorundadır.
ikinciIsim “Optional” bir değişken türüne sahiptir. (String?) Bu yüzden nil olmasında hiç bir sakınca yoktur.

Yeni Değerler Atama

Nil olan değişkenlere değerlerini atayalım ve hepsini tek bir değişkende toplayalım:

    
    var isim: String = "Ufuk"
    var ikinciIsim: String? = "Hüseyin"
    var soyIsim: String = "Köşker"

    isim = "Emirhan"
    ikinciIsim = "Can"
    soyIsim = "Erdoğan"

    var tamIsim = isim + ikinciIsim + soyIsim

    

Kodlamayı tamamladıktan sonra Xcode bize tekrar uyarı verecektir:

Nil olan değişkenlere değerlerini atadık ve hepsini başka bir değişkene atadık.

Optional(String?) olan bir değişkeni, optional olmayan(String) bir değişkene dönüştürmemizi istiyor. Bunu yapabilmek için Optional değişkenimizi Unwrap etmemiz gerekiyor.

Unwrapping Nedir ?

Unwrapping ile Optional olan değişken tiplerini normal tipteki değişkenlerimize çeviriyoruz.
Optional olan bir değişkeni normal bir değişken ile bir arada kullanamayız. İşte bunu yapmak için Optional olan değişkeni Unwrap etmeliyiz. Bunu yapabilmenin bir kaç yolu var.

  • Force Unwrapping
  • Implicit Unwrapping
  • Optional Binding

Force Unwrapping

Şimdilik tamIsim değişkenimizi yorum satırı haline getirelim.

    
    var isim: String = "Ufuk"
    var ikinciIsim: String? = "Hüseyin"
    var soyIsim: String = "Köşker"

    isim = "Emirhan"
    ikinciIsim = "Can"
    soyIsim = "Erdoğan"

    //var tamIsim = isim + ikinciIsim + soyIsim

    

Sonra değişkenlerimizi Print ile konsola yazdıralım ve aradaki farkı daha iyi anlayalım.

Değişkenlerimizi Print ile konsola’a yazdırdık.

Sonucumuzda ‘Optional(“Can”)’ yazıyor buna dikkat edelim.Sonucumuzu gördüğümüze göre Unwrap işlemine geçelim.

    
    var isim: String = "Ufuk"
    var ikinciIsim: String? = "Hüseyin"
    var soyIsim: String = "Köşker"

    isim = "Emirhan"
    ikinciIsim = "Can"
    soyIsim = "Erdoğan"

    //var tamIsim = isim + ikinciIsim + soyIsim

    print(isim)
    print(ikinciIsim)
    print(soyIsim)

    var yeniIkinciIsim = ikinciIsim! //Bu satırı ekledik.
    print(yeniIkinciIsim)

    

Ne yaptık ?

Force Unwrapping işlemimizi ! işeretini kullanarak yaptık. Optional değişkenimizi Unwrap ederek normal tipteki değişkene çeviriyoruz.
ikinciIsim ve yeniIkinciIsim normal tipte değişkenlerimiz oluyor. Hadi test edelim.

Force Unwrapping değişkeni konsola yazdıralım.

Gördüğünüz gibi ‘Hüseyin’ verisinin yanındaki ‘Optional’ yazısı gitti.

Force Unwrapping yaptığımız değişken nil olursa ne olur ?
mySecondName eğer nil olursa neler olur ineleyelim.

Unwrapping işlemini uyguladığımız değişkeni nil yaptık ve hata aldık. İşte bu büyük bir problemdir. Unwrap işlemi uygulanan değişken nil olursa uygulamamız crash olacak ve kapanacaktır. Bu da geliştiricilerin istemediği bir durumdur. Force Unwrapping yapmanız çok tavsiye edilmez. Eğer olacaklardan %100 eminseniz o zaman uygulayabilirsiniz.

Implicit Unwrapping

Burada değişkenimizi tanımladığımız sırada ! işaretini kullanırız. Derleyicimize; ‘Bu değişkeni kullanacağım zaman kesinlikle değer alacak’ demiş oluyoruz. Bu biraz sıkıntılı bir durum. ! işaretini koyarak derleyicimize söz verdik ve uygulama içerisinde sürekli takip edecek ve bir değer atanıp atanmadığını kontrol etmek zorunda kalacağız. Eğer değer atanmamışsa Xcode bize kızacak ve ‘Sen bana söz vermiştin bu değişken bir değer alacak ama bana boş geldi.’ diyip crash olacak.

Boş kutu örneğimize geri dönecek olursak eğer. Dolu olmasını beklediğimiz bir kutu bize boş gelirse sinirleniriz değil mi ?
İşte Xcode’da bize kızıp uygulamamızı kapatabiliyor.

Implicit Unwrapping değişken boş olamaz.

Örnek: Kullanıcıların kayıt olduğu ve kullanıcılardan ad, ikinci ad, soyad gibi bilgileri istediğinizi düşünün. Eğer siz ikinci ad’ın olduğu değişkeni Implicit Unwrapping yaparsanız ve kullanıcının ikinci adı yoksa uygulama crash olacaktır.

Hadi Deneyelim.

    
    var isim: String = "Ufuk"
    var ikinciIsim: String! = "Hüseyin"
    var soyIsim: String = "Köşker"

    print(isim)
    print(ikinciIsim)
    print(soyIsim)

    

Burada ikinciIsim değerini Implicit Unwrapping yaptık. Şimdi secondName değerini nil yapalım ve konsola bakalım.


Yine bir hata aldık. Biz yaptığımız bu uygulamada ikinciIsim değerini Implicit Unwrapping yapıp, kullanıcıdan ikinci isim istemeye kalkarsak kullanıcı da ‘Benim ikinci bir adım yok. Olmayan adımı yazmam’ der ve uygulamamız ile olan macerası başlamadan bitebilir.
Farkın daha iyi anlaşılabilmesi için aynı değişkenlere bir de Force Unwrapping işlemini uygulayalım.

    
    var isim: String = "Ufuk"
    var ikinciIsim: String? = nil
    var soyIsim: String = "Köşker"
    var implicitIkinciIsim: String = ikinciIsim!

    print(isim)
    print(ikinciIsim)
    print(soyIsim)

    

ikinciIsim: String? — Bu değişken nil olabilir.
imlicitIkinciIsim: String = ikinciIsim! — Burada yukarıdaki ikinciIsim değişkeninin boş gelmeyeceğini söylüyoruz. Ancak ikinciIsim değişkeni nil gelirse uygulamamız tekrar çökecektir. Hadi test edelim.

Burada hatayı implicitIkinciIsim değişkeninin bulunduğu satırda aldık. Çünkü ikinciIsim değişkeninin yanında ünlem işareti var ve bu değişkenin boş gelmeyeceğini söyledik, ancak boş geldi.
Hadi bu ünlem işaretinden ve uygulamamızın çökme derdinden kurtulalım.

Optional Binding

Burada yapacağımız işlem farklı görünse de ulaşacağımız sonuç ve amacımız Force Unwrapping ile aynıdır. Optional tipindeki bir değişkeni normal bir değişkene çevireceğiz. Diğer Unwrapping çeşitlerine göre en önemli avantajı değişkenimiz nil olsa bile uygulamamız crash olmadan çalışmaya devam edecektir. Hadi deneyelim.

    
    var isim: String = "Ufuk"
    var ikinciIsim: String? = "Hüseyin"
    var soyIsim: String = "Köşker"

    if let yeniIkinciIsim = ikinciIsim {
        print("\(isim) \(yeniIkinciIsim) \(soyIsim)")
    } else {
        print("\(isim) \(soyIsim)")
    }


    

Kodları yazdıysanız çalıştırıp konsola bir göz atalım.
Adım 1:
ikinsiIsim değişkenine bir değer verelim ve çalıştıralım.

Neler oluyor ?
Burada ikinciIsim değişkenimiz nil değerine sahip olmadığı için if koşulumuz sağlandı ve if içindeki işlemleri yaptı.
Bakalım nil olursa neler oluyor ?

Adım 2: ikinciIsim değişkeni nil yapalım.

    
    var isim: String = "Ufuk"
    var ikinciIsim: String? = nil
    var soyIsim: String = "Köşker"

    if let yeniIkinciIsim = ikinciIsim {
        print("\(isim) \(yeniIkinciIsim) \(soyIsim)")
    } else {
        print("\(isim) \(soyIsim)")
    }

    

Kodumuzu düzenledik ve çalıştırıp konsola bakalım:


Sıradaki

Tip Dönüşümleri

Bazı verilerin neden yalnızca daha geniş bir tür kullanılarak ifade edilebileceğini öğrenerek “Optional” konusundaki bilgilerinizi geliştireceksiniz.

Videolar

Swift Temellerine Giriş
Swift Temellerine Giriş
Teknolojinin Dili Kodlama
Teknolojinin Dili Kodlama
Playground Temelleri
Playground Temelleri
Veri Tipleri & Sabitler ve Değişkenler
Veri Tipleri & Sabitler ve Değişkenler
Operatörler
Operatörler
Kontrol Akışı
Kontrol Akışı
Fonksiyonlar
Fonksiyonlar
String'ler
String'ler
Objeler, Metotlar ve Özellikler
Objeler, Metotlar ve Özellikler
Xcode ile Tanışın
Xcode ile Tanışın
Struct
Struct
Class
Class
Koleksiyonlar
Koleksiyonlar
Döngüler
Döngüler
Xcode
Xcode
“Build”, “Run” ve “Debug”
“Build”, “Run” ve “Debug”
Arayüz Elemanlarını Yakından Tanıyın
Arayüz Elemanlarını Yakından Tanıyın
Dokümantasyon
Dokümantasyon
“Interface Builder” Temelleri
“Interface Builder” Temelleri
"UIKit" ile Kullanıcı Arayüzüne Giriş
"UIKit" ile Kullanıcı Arayüzüne Giriş
İlk Uygulama
İlk Uygulama
Kontrol Elemanları
Kontrol Elemanları
Autolayout & Stackview
Autolayout & Stackview
Optionals
Optionals
Tip Dönüşümleri
Tip Dönüşümleri
Guard
Guard
Uygulama Hayat Döngüsü ve Veri Modelleme
Uygulama Hayat Döngüsü ve Veri Modelleme
Scope Sabit & Değişken
Scope Sabit & Değişken
Enumerations
Enumerations
Protokoller
Protokoller
Segue ve Navigation Controller
Segue ve Navigation Controller
TabbarController
TabbarController
View Controller Hayat Döngüsü
View Controller Hayat Döngüsü
Basit Akışlar Oluşturmak
Basit Akışlar Oluşturmak
Uygulama Anatomisi ve Hayat Döngüsü
Uygulama Anatomisi ve Hayat Döngüsü
Model View Controller
Model View Controller
Uygulamanızda Veri Kaydedin
Uygulamanızda Veri Kaydedin
ScrollView
ScrollView
TableView Giriş
TableView Giriş
TableView İleri
TableView İleri
Verileri Kaydetmek
Verileri Kaydetmek
System View Controllers
System View Controllers
Uygulama Geliştirin
Uygulama Geliştirin
Karmaşık Veri Girişi Ekranları Oluşturmak
Karmaşık Veri Girişi Ekranları Oluşturmak
Closures
Closures
Extensions
Extensions
Pratik Animasyonlar
Pratik Animasyonlar
İnternet ile İletişime Geçin
İnternet ile İletişime Geçin
İnternet ile Çalışmak
İnternet ile Çalışmak
JSON
JSON
Concurrency
Concurrency