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.
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.
Ö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.
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.
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:
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 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.
Ş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.
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)
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.
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.
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.
Ö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.
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.
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: