Swift vs Objective-C: iOS Uygulamaları İçin Hangi Dili Kullanmalı?
Apple geçtiğimiz yıl düzenlenen WWDC2014 etkinliğinde yeni programlama dili Swift’i duyurmuştu. Bu duyuru birçok iOS programcısıyla birlikte iOS dünyasına girmeyi düşünen programcıların akıllarında birçok soru bıraktı. Bir taraftan yeni bir dilin getirilmesindeki amacın ne olduğu soruları, diğer taraftan Objective-C dilinin geleceği gibi sorular hala gündemi meşgul etmeye devam ediyor.
Apple bundan sonra yoluna Swift ile devam edeceğini belirtmekle birlikte Objective-C’ye desteğini de süreceğini açıklamıştı. Dolayısıyla birçok iOS uygulama geliştiricisi Swift öğrenip öğrenmeme konusunda kararsız durumda. Bununla birlikte iOS dünyasına girecek yazılımcılar ve yazılımcı adayları da Swift veya Objective-C dilleri arasında tercih yapma konusunda kararsız kalabiliyor. Bu yazıda biraz fikir verebilmek adına Objective-C ve Swift’i çeşitli açılardan karşılaştırdım.
Öncelikle iki dilin kısa tarihçesine hızlıca bir göz atalım:
Objective-C
Her taraftan farklı bir nesneye yönelimli programlama (NYP) dilinin çıktığı günümüzün aksine 1970’lerin sonu, 1980’lerin başında en yaygın ve kullanılabilir NYP dili Smalltalk’du. NYP’ya duyulan ihtiyacın artması ve kullanımının yaygınlaşmasıyla birlikte çeşitli bilim adamları dönemin ve günümüzün en popüler programlama dili olan C’ye NYP mantığını eklemek için kolları sıvadılar. Zaman içerisinde C++ ve Objective-C dilleri geliştirildi.
Bu sırada 1985’de Apple’dan kovulan Steve Jobs, NeXT isimli bir şirket kurmuş ve NeXTstep isimli bir bilgisayar üretmeye çalışıyordu. NeXT mühendisleri NeXTstep’de çalışacak işletim sistemini Objective-C ile yazmaya karar verdiler ve oluşturdukları kütüphanelerde ön ek olarak bilgisayarın ismine ithafen “NS” kısaltmasını kullandılar. Zaman içinde bu kütüphanelerde çok büyük değişiklikler olsa da “NS” kısaltması sabit kaldı.
1990’lara gelindiğinde Apple pazar payını kaybetmeye başlamıştı; Mac OS beklentileri artık karşılayamıyordu. Apple yeni işletim sistemi projeleri başarıya ulaşamayınca 1996’da NeXT’i satın aldı ve Mac OS X, NeXT’in tecrübesi ve kütüphaneleri dolayısıyla Objective-C ile geliştirilmeye başlandı. Objective-C OS X’in temelini oluşturması nedeniyle Apple içerisinde kalıcı hale geldi. Apple 2006 yılında çeşitli özellikler eklediği Objective-C 2.0’ı yayınladı ve iOS’da da Objective-C’yi ana programlama dili olarak belirledi.
Swift
Swift’in tarihçesi doğal olarak epey kısa; dil Apple’da geliştirici araçları biriminde çalışan (ve daha sonra bu birimin başına geçen) Chris Lattner‘ın emeğinin sonucunda ortaya çıktı. 2010 yılında gizlice Swift’i geliştirmeye başlayan Lattner dilin temel özellikleri çalışır hale geldiği 2011 yılında Apple’daki üstlerine sırrını açıklıyor ve ardından kısa bir süre sonra Swift üzerinde çalışan ekip büyüyor. Şirket içinde yürütülen yaklaşık 2.5 yıllık gizli çalışmanın ardından da Swift geliştiricilere duyuruluyor.
İki dilin tarihçesi sıkıcı geldiyse o zaman biraz da teknik detayları inceleyelim:
Sözdizimi(Syntax) Farklılıkları
Objective-C çok uzun süredir farklı sözdizimi yüzünden eleştiri oklarının hedefi olmuş durumda. Özellikle C# veya Java gibi modern dillere alışmış programcılar için Smalltalk ve C’nin birleşiminden doğan söz dizimi tam bir kabus. Kısa (ve aslen kullanışsız) bir örnekle incelersek;
NSArray * dizi = [[NSArray alloc] initWithArray: @[@"Selam", @"Devnot"] copyItems: NO];
Görüldüğü üzere tek bir satır içerisinde “*”, “[]” ve “@” gibi yabancı gözüken ve alışık olmayanlar için okumayı zorlaştıran pek çok karakter var. Swift ise Objective-C’ye nazaran daha “tanıdık” bir söz dizimine sahip. Benzer bir örneğe bakarsak;
let dizi = Array<String>(count: 5, repeatedValue: "Devnot");
Her ne kadar Swift’de kod okumak daha kolay gibi dursa da işin asıl pek öyle değil. Mesela Apple’ın resmi Swift dökümanında geçen aşağıdaki kodu “optional” ve “optional chaning” kavramları konusunda fikriniz yoksa doğru bir şekilde anlamanız epey zor;
if let johnsStreet = john.residence?.address?.street { println("John's street name is \(johnsStreet).") } else { println("Unable to retrieve the address.") }
Ayrıca kavram konusunda fikriniz olsa bile hem Objective-C hem Swift’de karışık gelecek bazı söz dizimleri de mevcut. Örneğin pek çok programcı closure kavramına aşina olsa da hem Objective-C hem de Swift‘de closure söz dizimi epey karmaşık.
Özetle Swift başta daha “arkadaş canlısı” gözükse de diğer dillere göre garip ve yabancı pek çok noktası da mevcut.
İki Dilin Yetenekleri
Swift yeni bir dil olması sebebiyle Objective-C’ye göre daha yetenekli; geliştiricileri diğer dillerde bulunan ve sevilen özellikleri bir araya toplamışlar. Bir fonksiyondan birden çok değer döndürme (Tupple), değişken tanımlarken her seferinde tipini yazmaya gerek duyulmaması(Type Inference), Class-Struct-Enum içerisinde başka Class-Struct-Enum tanımlayabilme (Nested Types), +, -, *, / gibi standart operatörleri kendi tanımlarının dışında kullanabilme (Operator Overloading) ve hatta kendi operatörünü tanımlama gibi Objective-C’de olmayan pek çok özellik dile eklenmiş.
Yapacağınız işe bağlı olarak Objective-C’de de pointerlara doğrudan erişilebiliyor olması ve preprocessor komutları hayatınızı baya kolaylaştırabilir ama bunları gerçekleştirmenin de Swift’de çeşitli yolları mevcut.
Esneklik
Swift’in kod yazma açısından Objective-C’ye göre çok daha esnek olduğunu söyleyebiliriz. Apple’ın resmi dökümantasyonunda neredeyse her konu için “isterseniz böyle de yazabilirsiniz” şeklinde örnekler bulmanız mümkün. Örneğin aşağıdaki 4 satır da String’lerden oluşan bir dizi tanımlıyor;
let dizi = [String](); let dizi2 = Array<String>() let dizi3: [String] = Array<String>(); let dizi4: Array<String> = [String]()
Elbette Objective-C’de de diziyi birden çok şekilde tanımlamak mümkün ama Objective-C’de farklılıklar genel olarak söz diziminden değil farklı metotların çağrılmasından kaynaklanıyor. Bu arada örnek kodda noktalı virgülün bazı satırlarda olmaması da hata değil, noktalı virgül kullanımı JavaScript gibi Swift’de de isteğe bağlı.
Swift söz diziminin esnekliği konu closure’lar olunca daha net ortaya çıkıyor. Aşağıdaki 6 örnek de Apple’ın Swift dökümanında bulunuyor ve tahmin edeceğiniz üzere hepsi aynı işi yapıyor;
reversed = sorted(names, { (s1: String, s2: String) -> Bool in return s1 > s2 }) reversed = sorted(names, { s1, s2 in return s1 > s2 } ) reversed = sorted(names, { s1, s2 in s1 > s2 } ) reversed = sorted(names, { $0 > $1 } ) reversed = sorted(names, >) reversed = sorted(names) { $0 > $1 }
Swift hem Objective-C ile uyumluyken hem de Objective-C’nin desteklemediği pek çok yeni özelliği destekliyor, dolayısıyla bu da programcıya söz dizimi dışında da bir esneklik sağlıyor. Buna en güzel örnek olarak generic kullanımı verilebilir;
func devnot (değişken: Any) -> Bool { if değişken is String { return true; } else { return false; } } func devnotGeneric<T>(değişken: T) -> Bool { if değişken is String { return true; } else { return false; } }
“Any” ve “AnyObject” Objective-C ile uyumluluk açısından Swift’e eklenen ve her nesnenin atanabileceği veri tipleri. Generic ise benzer amaçlarla kullanılan ve kısmen daha esnek olan bir yapı. Ancak bir kısıtlama olmadığı için ikisini bir arada kullanmak mümkün. (Ek olarak belirteyim, değişken adı olarak “değişken”‘i kullanmam yanlış değil, Swift Unicode karakterleri desteklediği için değişken isimlerinde Türkçe veya emoji karakterleri kullanılabiliyor)
Her ne kadar esneklik güzel birşey gibi görünse de eğer başkalarının kodlarıyla sık sık haşır neşir oluyorsanız veya kalabalık bir grupla belirli kodlama standartı olmadan çalışıyorsanız başınızı çok büyük ihtimalle ağrıtacaktır.
Hata Önleme ve Ayıklama
Derleyici ve IDE’ler her ne kadar zeki olsalar da bazen programcıların yaptığı küçük hataları farkedemeyebiliyorlar. Genelde bunlar çok büyük bir soruna neden olmasalar da Apple’ın goto fail; rezaletinde olduğu gibi ciddi sonuçları da olabiliyor. Swift geliştirilirken de bu hataları azaltmak adına pek çok önlem alınmış;
- If-Else blokları süslü parantez ile kullanılmak zorunda.
- Switch-Case bloklarında tüm durumlar tanımlanmalı.
- Switch-Case bloklarında her durum için ayrı ayrı “break” yazmaya gerek yok, bunun yerine eğer kodun sonraki duruma devam etmesi isteniyorsa özellikle belirtiliyor.
- Eğer mantıksal bir kontrol her zaman doğru veya yanlışsa derleyici hata veriyor.
- Değişkene atama yapmadan veya tip uyumsuzluğunda değişkeni kullanmak mümkün değil.
- Eğer işlem sırasında sayılarda taşma olursa program hiç birşey olmamış gibi devam etmek yerine sonlanıyor.
- Değişkenin “NULL” (Swift ve Objective-C’deki karşılığı “nil”) olup olamayacağı düşünülerek değişkenler farklı tanımlanıyor.
Bunlar kağıt üzerinde çok güzel gözükse de ne yazık ki özellikle tip uyumsuzluğu durumunda derleyicinin verdiği hatalar çoğu zaman birşey ifade etmiyor. Küçük birşey yazarken bile ” Cannot convert expression’s type ‘($T1, $T2, $T3) -> $T0′ to type ‘()’ ” gibi manasız hataların karşınıza çıkması olası.
Diğer bir sıkıntı da Xcode ve Swift’in halen tam olarak anlaşamıyor olması. Xcode Swift’i yeniden düzenleyemediği gibi (değişken adını kolayca değiştirmek vs) hata ayıklarken de programıcya çok yardımcı olmuyor. Objective-C’nin aksine basit bir değişken değerini görmek için bile lldb komutlarını kullanmak veya fazladan kod yazmak açıkcası epey sinir bozucu.
Performans
Apple Swift’in Objective-C’ye göre çok daha hızlı olduğunu iddia ediyor. Henüz bunu kesin olarak doğrulayan bir bulgu olmamakla birlikte Swift’in ilk sürümüyle birlikte basit testlerde yaklaşık aynı hızlarda sonuçlar veriyor, zaten teorik olarak da Objective-C’nin çalışma şekli nedeniyle Swift’in biraz daha hızlı olması normal. Benim çeşitli project euler sorularında yaptığım denemelerde Swift genelde daha yavaş kalsa da yaptığımın çok ciddi bir test olmadığını da belirtmem gerekiyor.
Bu arada eğer uygulamanızda Apple kütüphanelerini sıkça kullanıyorsanız Swift veya Objective-C kullanmanız performans açısından pek bir fark yaratmayabilir, Apple Swift için bazı düzenlemeler yapsa da kütüphanelerinde genel olarak C, C++ ve Objective-C kullanıyor.
Yukarıdaki resim Swift’in duyurulduğu sunumdan. Apple kompleks dizi sıralama algoritmalarında Swift’in Objective-C ve Python’dan daha hızlı olduğunu bu grafikle dile getirmişti.
Hangisini Öğrenmeli?
Gelelim bilhassa iOS programlamaya yeni başlayanlar için en can alıcı soruya. Objective-C söz dizimi biraz korkutucu gözükse de Swift’in özelliklerini ve püf noktalarını öğrenmenin biraz daha zor olduğunu söyleyebilirim. Diğer yandan zaten iOS’a veya OS X’e nasıl uygulama geliştireceğinizi öğrenirken vaktinizin büyük kısmını Apple kütüphanelerini öğrenerek harcayacaksınız. Yukarıda açıkladığım maddeleri dikkate aldığımızda sözdizimi, ek özellikler ve yetenekler açısından Swift dilinin daha ağır bastığını söyleyebiliriz. Yine Apple’ın yeni çıkardığı bu dilin gelişimine ilerleyen yıllarda daha fazla destek olacağını söyleyebiliriz. Diğer taraftan Swift detaylı şekile öğrenmenin Objective-C’den daha zor olduğunu bu paragrafın başında söylediğim şekilde yinelemek isterim.
Mesleki açıdan değerlendirecek olursak eğer kendi uygulamanızı yazmak istiyorsanız ve yeterli vaktiniz varsa Swift öğrenmenizi tavsiye edebilirim. Vaktiniz kısıtlıysa veya bir firmaya girmek ve iOS / OS X üzerine çalışmak istiyorsanız Objective-C öğrenmeniz daha mantıklı olacaktır.
Sonuç
Swift de Objective-C de mükemmel değil. Swift 2010’da geliştirilmeye başlamasının etkisiyle daha modern çözümler sunmakla birlikte Objective-C de hem iOS ve OS X’in merkezinde olması hem de geliştiriciler tarafından yaygın kullanımı nedeniyle uzun bir süre daha sektörde önemli bir yere sahip olacak. Bu noktada mutlaka Swift öğrenmeliyim veya Objective-C’nin artık geleceği yoktur gibi söylemlerin çok gerçekçi olmadığını belirtmekte fayda var.
YÜCEL UZUN
Konuk Yazar
2 Comments
Buildera
25 Mayıs 2015 at 01:22Hoş bir yazı olmuş.Her iki taraftada birşeyler üreten birisi olarak swift öğrenmenin gereksiz olduğunu söyleyebilirim.Objective 25 yılı aşkın bir süredir Apple bünyesinde.. LLVM göz önünde bulundurulduğunda bazı elegance özellikler gözardı edilebilir..
Serdar
21 Nisan 2016 at 04:44Makale gercektende çok güzel hazirlanmış çok teşekkürler, yanliz söyle bir sorum var, eger hem android hemde ios için app yazmak istiyorsam hangi dili tercih etmeliyim? (Hybrit sistemler hariç)