Objective-C

bilgipedi.com.tr sitesinden
Objective-C
Paradigması yansıtıcı, sınıf tabanlı, nesne yönelimli
İlk çıkışı 1983
Tasarımcı Brad Cox ve Tom Love
Geliştirici Apple
Kararlı sürüm

2.0

(26 Ekim 2007 (15 yıl önce))
Tip sistemi statik, dinamik, zayıf
Önemli uygulamaları Clang, GCC
Etkilendikleri C, Smalltalk
Etkiledikleri Java, Objective-J, TOM
İşletim sistemi Çapraz platform
Olağan dosya uzantıları .h, .m, .mm
Web sitesi Apple Developer — Objective-C

Objective-C, C'nin üzerine yazılmış, yansımalı, nesne yönelimli bir programlama dilidir. ObjC, Objective C ve Obj-C olarak da anılır.

Günümüzde OpenStep standardı üzerine kurulu olan macOS ve GNUstep işletim sistemlerinde kullanılmaktadır. Objective-C'nin en yaygın olarak kullanıldığı alan Cocoa çatısının kullanıldığı yazılımlardır. Bu özel kütüphanelere erişime ihtiyaç duymayan bir Objective-C programı Objective-C derleyicisi içeren gcc ile derlenebilir.

1980'li yıllarda yazılım mühendisliğindeki genel eğilim yapısal programlamaya yönelikti. Bu yaklaşım sayesinde karmaşık problemler ufak parçalara bölünüp ufak parçaların çözülmesiyle büyük çözüme ulaşılıyordu. Fakat problemler büyüyüp daha da karmaşık hale gelmeye başlayınca bu yaklaşım yetersiz kalmaya başladı.

Bu noktada çoğu geliştirici nesne yönelimli programlamayı bir çözüm olarak görmeye başladı. Smalltalk tarafından öncülüğü yapılmış bu akım, programları fonksiyonel nesnelerin birleşimi olarak yorumlamaya dayalıydı. Smalltalk nesneye yönelik programlama ile zamanında yapısal programlamanın zayıf kaldığı noktaların çoğunda başarılıydı. Bu avantajdan dolayı zamanın en gelişmiş sistemleri Smalltalk ile yazılmıştı. Yalnız Smalltalk'ın en büyük sorunu bir sanal makine üzerinde çalışıyor olmasıydı. Bu gereksinimden dolayı ya çok bellek gerektiren sistemler gerektiriyordu ya da yavaş çalışmasını göze almak gerekiyordu.

Objective-C 1980'lerde Brad Cox tarafından Stepstone adlı şirkette geliştirildi. Cox'un takıldığı sorun yazılımlardaki bileşenlerin tekrar kullanılabilmesiydi. Bir başka deyişle, bir problem nesneye yönelik yöntemlerle parçalarına ayrılmış ve bu parçaların bazıları çalışır duruma getirilmiş ise, bu parçaları sorunsuzca başka çözümlerde de kullanmayı kolaylaştırmak lazımdı. Her ne kadar nesne yönelimli yazılım teorik olarak bunu öngörse de, zamanın araçları ile bunu başarmak emek isteyen bir işti. Cox hayal ettiği kolaylığı sağlamak için aslında bir iki ufak değişikliğin yeterli olacağını düşündü. Programlama dili her şeyden önce nesneleri esnek bir şekilde desteklemeli, kullanışlı ve zaman kazandıran kütüphanelerle gelmeli ve kod ve kaynakların ortamlar arası kullanımını kolaylaştırmalıydı.

Cox'un temel tasarımı 1986 yılında Nesne Yönelimli Programlama, Evrimsel bir yaklaşım (Object-oriented Programming, An Evolutionary Approach) adlı kitabında yayınlandı. Kitapta bileşenlerin yeniden kullanımı konusunun sadece programlama dilinden oluşmadığını vurgulamasına rağmen okuyucuların dikkatlerini sadece dile odaklamalarına, Objective-C'yi sunduğu önerilerden ayrı olarak algılamalarına engel olamadı.

Objective-C, C programlama diline Smalltalk tarzı mesajlaşma ekleyen genel amaçlı, nesne yönelimli bir programlama dilidir. İlk olarak 1980'lerin başında Brad Cox ve Tom Love tarafından geliştirilen bu dil, NeXTSTEP işletim sistemi için NeXT tarafından seçilmiştir. Objective-C, 2014 yılında Swift'in piyasaya sürülmesine kadar Apple tarafından macOS (NeXTSTEP'ten türemiştir) ve iOS uygulamalarını geliştirmek için kendi uygulama programlama arayüzlerini (API'ler), Cocoa ve Cocoa Touch'ı kullanarak desteklenen standart programlama diliydi.

Apple dışı işletim sistemleri için geliştirilen veya Apple'ın API'lerine bağımlı olmayan Objective-C programları, GNU GCC veya LLVM/Clang tarafından desteklenen herhangi bir platform için de derlenebilir.

Objective-C kaynak kodu 'mesajlaşma/uygulama' program dosyaları genellikle .m dosya adı uzantısına sahipken, Objective-C 'başlık/arayüz' dosyaları C başlık dosyalarında olduğu gibi .h uzantısına sahiptir. Objective-C++ dosyaları .mm dosya uzantısı ile gösterilir.

Tarihçe

Objective-C öncelikle Brad Cox ve Tom Love tarafından 1980'lerin başında Productivity Products International (PPI) adlı şirketlerinde yaratılmıştır.

Her ikisi de şirketlerini kurmadan önce 1981 yılında ITT Corporation'ın Programlama Teknolojisi Merkezi'nde Smalltalk ile tanışmışlardı. Objective-C üzerindeki ilk çalışmalar da bu döneme dayanıyor. Cox, yazılım tasarımı ve programlamada gerçek yeniden kullanılabilirlik sorunlarıyla ilgileniyordu. Smalltalk gibi bir dilin ITT'deki sistem geliştiricileri için geliştirme ortamları oluşturmada çok değerli olacağını fark etti. Ancak o ve Tom Love, ITT'nin telekom mühendisliği ortamında C ile geriye dönük uyumluluğun kritik öneme sahip olduğunun da farkındaydı.

Cox, Smalltalk'ın bazı yeteneklerini eklemek için C için bir ön işlemci yazmaya başladı. Çok geçmeden C diline nesne yönelimli bir eklenti geliştirdi ve buna Nesne Yönelimli Ön Derleyici anlamına gelen "OOPC" adını verdi. Love 1982'de Schlumberger Research tarafından işe alındı ve Smalltalk-80'in ilk ticari kopyasını edinme fırsatı buldu, bu da beyin çocuklarının gelişimini daha da etkiledi. Cox, gerçek bir ilerleme kaydedilebileceğini göstermek için birbiriyle değiştirilebilir yazılım bileşenleri oluşturmanın mevcut araçlarda sadece birkaç pratik değişiklik gerektirdiğini gösterdi. Özellikle, nesneleri esnek bir şekilde desteklemeleri, kullanılabilir bir dizi kütüphaneyle birlikte gelmeleri ve kodun (ve kodun ihtiyaç duyduğu tüm kaynakların) platformlar arası tek bir formatta paketlenmesine izin vermeleri gerekiyordu.

Love ve Cox sonunda, Objective-C derleyicisini sınıf kütüphaneleriyle birleştiren ürünlerini ticarileştirmek için PPI'ı kurdular. Cox, 1986 yılında Objective-C'nin ana tanımını Object-Oriented Programming, An Evolutionary Approach adlı kitapta orijinal haliyle yayınladı. Her ne kadar yeniden kullanılabilirlik sorununda Objective-C'nin sağladığından daha fazlası olduğunu belirtmeye dikkat etse de, dil kendisini sık sık diğer dillerle özellik özellik karşılaştırılırken buldu.

NeXT aracılığıyla popülerleşme

1988 yılında NeXT, Objective-C'yi StepStone'dan (Objective-C ticari markasının sahibi olan PPI'ın yeni adı) lisansladı ve GCC derleyicisini Objective-C'yi destekleyecek şekilde genişletti. NeXT, NeXTSTEP kullanıcı arayüzünün ve Interface Builder'ın dayandığı AppKit ve Foundation Kit kütüphanelerini geliştirdi. NeXT iş istasyonları pazarda büyük bir etki yaratamazken, araçlar sektörde geniş çapta övgüyle karşılandı. Bu durum NeXT'in donanım üretimini bırakıp yazılım araçlarına odaklanmasına ve NeXTSTEP'i (ve OPENSTEP'i) özel programlama için bir platform olarak satmasına yol açtı.

GPL'nin şartlarını aşmak için NeXT başlangıçta Objective-C ön ucunu ayrı olarak göndermeyi ve kullanıcının derleyici çalıştırılabilir dosyasını üretmek için GCC ile bağlamasına izin vermeyi amaçlamıştı. Başlangıçta Richard M. Stallman tarafından kabul edilmesine rağmen, Stallman GNU'nun avukatlarına danıştıktan sonra bu plan reddedildi ve NeXT Objective-C'yi GCC'nin bir parçası yapmayı kabul etti.

GCC'yi genişletme çalışmaları StepStone'dan NeXT'e katılan Steve Naroff tarafından yönetildi. Derleyici değişiklikleri GPL lisans koşulları uyarınca kullanıma sunuldu, ancak çalışma zamanı kütüphaneleri kullanıma sunulmadı ve açık kaynak katkısı genel halk için kullanılamaz hale geldi. Bu durum, diğer tarafların açık kaynak lisansı altında bu tür çalışma zamanı kütüphaneleri geliştirmesine yol açtı. Daha sonra Steve Naroff, Apple'da Clang'ın Objective-C ön ucunu oluşturmak için yapılan çalışmalara da katkıda bulunmuştur.

GNU projesi, OpenStep standardını temel alan GNUstep adlı Cocoa'nın özgür yazılım uygulaması üzerinde çalışmaya başladı. Dennis Glatting 1992 yılında ilk GNU Objective-C çalışma zamanını yazdı. 1993'ten beri kullanımda olan GNU Objective-C çalışma zamanı, Kresten Krab Thorup tarafından Danimarka'da bir üniversite öğrencisiyken geliştirilmiştir. Thorup ayrıca 1993'ten 1996'ya kadar NeXT'te çalışmıştır.

Apple geliştirme ve Swift

Apple Computer, 1996 yılında NeXT'i satın aldıktan sonra, o zamanki yeni işletim sistemi Mac OS X'te OpenStep'i kullandı. Buna Objective-C, NeXT'nin Objective-C tabanlı geliştirici aracı Project Builder ve arayüz tasarım aracı Interface Builder da dahildi. Her ikisi de daha sonra tek bir uygulama olan Xcode'da birleştirildi. Apple'ın mevcut Cocoa API'sinin çoğu OpenStep arayüz nesnelerine dayanmaktadır ve aktif geliştirme için kullanılan en önemli Objective-C ortamıdır.

WWDC 2014'te Apple, "C olmadan Objective-C" olarak nitelendirilen yeni bir dil olan Swift'i tanıttı.

Sözdizimi

Objective-C, C'nin üzerinde ince bir katmandır ve C'nin "katı bir üst kümesidir", yani herhangi bir C programını bir Objective-C derleyicisiyle derlemek ve bir Objective-C sınıfına C dili kodunu serbestçe dahil etmek mümkündür.

Objective-C nesne sözdizimini Smalltalk'tan alır. Nesne yönelimli olmayan işlemler için tüm sözdizimi (ilkel değişkenler, ön işleme, ifadeler, işlev bildirimleri ve işlev çağrıları dahil) C'ninkilerle aynıyken, nesne yönelimli özellikler için sözdizimi Smalltalk tarzı mesajlaşmanın bir uygulamasıdır.

Mesajlar

Nesne yönelimli programlamanın Objective-C modeli, nesne örneklerine mesaj aktarımına dayanır. Objective-C'de bir yöntem çağrılmaz; bir mesaj gönderilir. Bu, C++ tarafından kullanılan Simula tarzı programlama modelinden farklıdır. Bu iki kavram arasındaki fark, yöntem veya mesaj adı tarafından başvurulan kodun nasıl yürütüldüğüdür. Simula tarzı bir dilde, yöntem adı çoğu durumda derleyici tarafından hedef sınıftaki bir kod bölümüne bağlanır. Smalltalk ve Objective-C'de, bir mesajın hedefi çalışma zamanında çözülür ve alıcı nesnenin kendisi mesajı yorumlar. Bir yöntem, bir seçici veya SEL - her mesaj adı için benzersiz bir tanımlayıcı, genellikle yalnızca adını temsil eden NUL ile sonlandırılmış bir dize - ile tanımlanır ve onu uygulayan bir C yöntem işaretçisine çözümlenir: bir IMP. Bunun bir sonucu olarak mesaj geçirme sisteminde tip denetimi yoktur. Mesajın yönlendirildiği nesnenin - alıcı - bir mesaja yanıt vereceği garanti edilmez ve yanıt vermezse bir istisna ortaya çıkar.

Mesaj yöntemini obj işaretçisinin gösterdiği nesneye göndermek için C++'da aşağıdaki kod gerekir:

obj->method(argument); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Messages&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Messages <span style="color:#dddddd">ⓘ</span>]</span>

Objective-C'de bu aşağıdaki gibi yazılır:

[obj yöntem:argüman]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Messages&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Messages <span style="color:#dddddd">ⓘ</span>]</span>

"Yöntem" çağrısı derleyici tarafından objc_msgSend(id self, SEL op, ...) çalışma zamanı işlevleri ailesine çevrilir. Farklı uygulamalar super gibi modern eklemeleri ele alır. GNU ailelerinde bu fonksiyon objc_msg_sendv olarak adlandırılır, ancak objc_msg_lookup altında modern bir arama sistemi lehine kullanımdan kaldırılmıştır.

Her iki programlama tarzının da güçlü ve zayıf yanları vardır. Simula (C++) tarzında nesne yönelimli programlama, mümkün olduğunda derleme zamanı bağlama kullanarak çoklu kalıtıma ve daha hızlı yürütmeye izin verir, ancak varsayılan olarak dinamik bağlamayı desteklemez. Ayrıca, soyut olmadıkları sürece tüm yöntemleri karşılık gelen bir uygulamaya sahip olmaya zorlar. Objective-C'de kullanılan Smalltalk tarzı programlama, mesajların uygulanmadan gitmesine ve yöntemin çalışma zamanında uygulamasına çözümlenmesine izin verir. Örneğin, bir mesaj, çalışma zamanı hataları üretme korkusu olmadan, yalnızca bazılarının yanıt vermesi beklenen bir nesne koleksiyonuna gönderilebilir. Mesaj iletimi ayrıca bir nesnenin derleme zamanında tanımlanmasını gerektirmez. Türetilmiş nesnede çağrılacak yöntem için yine de bir uygulama gereklidir. (Dinamik (geç) bağlamanın daha fazla avantajı için aşağıdaki dinamik yazma bölümüne bakın).

Arayüzler ve uygulamalar

Objective-C, bir sınıfın arayüzünün ve uygulamasının ayrı ayrı bildirilmiş kod bloklarında olmasını gerektirir. Geleneksel olarak, geliştiriciler arayüzü bir başlık dosyasına ve uygulamayı bir kod dosyasına yerleştirir. Normalde .h ile sonlandırılan başlık dosyaları C başlık dosyalarına benzerken, normalde .m ile sonlandırılan uygulama (yöntem) dosyaları C kod dosyalarına çok benzeyebilir.

Arayüz

Bu, C++ veya Python gibi diğer nesne yönelimli dillerde kullanılan sınıf bildirimlerine benzer.

Bir sınıfın arayüzü genellikle bir başlık dosyasında tanımlanır. Yaygın bir kural, başlık dosyasına sınıfın adının verilmesidir, örneğin Ball.h, Ball sınıfının arayüzünü içerir.

Bir arayüz bildirimi şu biçimi alır:

@arayüz sınıfadı : üstsınıfadı {
  // örnek değişkenler
}
+ classMethod1;
+ (return_type)classMethod2;
+ (return_type)classMethod3:(param1_type)param1_varName; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Interface&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Interface <span style="color:#dddddd">ⓘ</span>]</span>

- (return_type)instanceMethod1With1Parameter:(param1_type)param1_varName;
- (return_type)instanceMethod2With2Parameters:(param1_type)param1_varName
                              param2_callName:(param2_type)param2_varName;
@end

Yukarıdaki ifadelerde artı işaretleri sınıf yöntemlerini veya sınıfın kendisi üzerinde çağrılabilen (bir örnek üzerinde değil) yöntemleri, eksi işaretleri ise yalnızca sınıfın belirli bir örneği üzerinde çağrılabilen örnek yöntemlerini belirtir. Sınıf yöntemlerinin ayrıca örnek değişkenlerine erişimi yoktur.

Yukarıdaki kod kabaca aşağıdaki C++ arayüzüne eşdeğerdir:

class classname : public superclassname {
korumalı:
  // örnek değişkenler <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Interface&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Interface <span style="color:#dddddd">ⓘ</span>]</span>

public:
  // Sınıf (statik) fonksiyonları
  static void *classMethod1();
  static return_type classMethod2();
  static return_type classMethod3(param1_type param1_varName); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Interface&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Interface <span style="color:#dddddd">ⓘ</span>]</span>

  // Örnek (üye) fonksiyonlar
  return_type instanceMethod1With1Parameter(param1_type param1_varName);
  return_type
  instanceMethod2With2Parameters(param1_type param1_varName,
                                 param2_type param2_varName = default);
};

instanceMethod2With2Parameters:param2_callName: ifadesinin, C/C++'da doğrudan bir eşdeğeri bulunmayan seçici segmentlerinin argüman ifadeleriyle iç içe geçmesini gösterdiğine dikkat edin.

Dönüş türleri herhangi bir standart C türü, genel bir Objective-C nesnesine işaretçi, NSArray *, NSImage * veya NSString * gibi belirli bir nesne türüne işaretçi veya yöntemin ait olduğu sınıfa işaretçi (instancetype) olabilir. Varsayılan dönüş tipi genel Objective-C tipi id'dir.

Yöntem argümanları, yöntem adının bir parçası olan argümanı etiketleyen bir adla başlar, ardından iki nokta üst üste ve ardından parantez içinde beklenen argüman türü ve argüman adı gelir. Etiket atlanabilir.

- (void)setRangeStart:(int)start end:(int)end;
- (void)importDocumentWithName:(NSString *)name
      withSpecifiedPreferences:(Preferences *)prefs
                    beforePage:(int)insertPage; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Interface&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Interface <span style="color:#dddddd">ⓘ</span>]</span>

Arayüz tanımının bir türevi, mevcut sınıflara yöntem eklenmesine olanak tanıyan kategoridir.

Uygulama

Arayüz yalnızca sınıf arayüzünü bildirir, yöntemlerin kendisini bildirmez: asıl kod uygulama dosyasına yazılır. Uygulama (yöntem) dosyaları normalde, orijinal olarak "mesajlar" anlamına gelen .m dosya uzantısına sahiptir.

@implementation sınıf adı
+ (return_type)classMethod {
  // uygulama
}
- (return_type)instanceMethod {
  // uygulama
}
@end <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Implementation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Implementation <span style="color:#dddddd">ⓘ</span>]</span>

Yöntemler, arayüz bildirimleri kullanılarak yazılır. Objective-C ve C karşılaştırması:

- (int)method:(int)i {
  return [self square_root:i];
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Implementation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Implementation <span style="color:#dddddd">ⓘ</span>]</span>
int fonksiyon(int i) {
  return square_root(i);
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Implementation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Implementation <span style="color:#dddddd">ⓘ</span>]</span>

Sözdizimi, argümanların sözde adlandırılmasına izin verir.

- (void)changeColorToRed:(float)red green:(float)green blue:(float)blue {
  //... Uygulama ...
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Implementation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Implementation <span style="color:#dddddd">ⓘ</span>]</span>

// Bu şekilde çağrılır:
[myColor changeColorToRed:5.0 green:2.0 blue:6.0];

Bir yöntemin dahili gösterimleri Objective-C'nin farklı uygulamaları arasında farklılık gösterir. Eğer myColor Color sınıfındaysa, -changeColorToRed:green:blue: örnek metodu dahili olarak _i_Color_changeColorToRed_green_blue olarak etiketlenebilir. Buradaki i, sınıf ve ardından yöntem adları eklenerek ve iki nokta üst üste alt çizgi olarak değiştirilerek bir örnek yönteme atıfta bulunmak içindir. Parametrelerin sırası yöntem adının bir parçası olduğundan, gerçek adlandırılmış parametrelerde olduğu gibi kodlama stiline veya ifadeye uyacak şekilde değiştirilemez.

Ancak, işlevin dahili adları nadiren doğrudan kullanılır. Genel olarak, mesajlar Objective-C çalışma zamanı kütüphanesinde tanımlanan fonksiyon çağrılarına dönüştürülür. Alıcının (mesajın gönderildiği nesne) sınıfının çalışma zamanına kadar bilinmesi gerekmediğinden, hangi yöntemin çağrılacağı bağlantı zamanında bilinmek zorunda değildir.

Hazırlama

Bir Objective-C sınıfı yazıldıktan sonra örneklendirilebilir. Bu, önce sınıfın başlatılmamış bir örneğini (bir nesne) ayırarak ve sonra onu başlatarak yapılır. Her iki adım da tamamlanana kadar bir nesne tam olarak işlevsel değildir. Bu adımlar tek bir kod satırıyla gerçekleştirilmelidir, böylece hiçbir zaman ilklendirilmemiş bir nesne tahsis edilmemiş olur (ve -init çağrıldığı nesneden farklı bir nesne döndürebileceğinden ara sonucu saklamak akıllıca değildir).

Varsayılan, parametresiz başlatıcı ile başlatma:

MyObject *foo = [[MyObject alloc] init]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Instantiation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Instantiation <span style="color:#dddddd">ⓘ</span>]</span>

Özel bir başlatıcı ile başlatma:

MyObject *foo = [[MyObject alloc] initWithString:myString]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Instantiation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Instantiation <span style="color:#dddddd">ⓘ</span>]</span>

Özel bir ilklendirme yapılmadığı durumlarda, alloc-init mesajları yerine genellikle "new" yöntemi kullanılabilir:

MyObject *foo = [MyObject new]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Instantiation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Instantiation <span style="color:#dddddd">ⓘ</span>]</span>

Ayrıca, bazı sınıflar sınıf yöntemi başlatıcıları uygular. new gibi, +alloc ve -init'i birleştirirler, ancak +new'den farklı olarak, otomatik serbest bırakılmış bir örnek döndürürler. Bazı sınıf yöntem başlatıcıları parametre alır:

MyObject *foo = [MyObject object];
MyObject *bar = [MyObject objectWithString:@"Wikipedia :)"]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Instantiation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Instantiation <span style="color:#dddddd">ⓘ</span>]</span>

alloc mesajı, bir nesne için tüm örnek değişkenlerini tutmaya yetecek kadar bellek ayırır, tüm örnek değişkenlerini sıfır değerine ayarlar ve belleği sınıfın bir örneğine dönüştürür; başlatma sırasında hiçbir noktada bellek üst sınıfın bir örneği değildir.

init mesajı, oluşturulduktan sonra örneğin kurulumunu gerçekleştirir. init yöntemi genellikle aşağıdaki gibi yazılır:

- (id)init {
    self = [super init];
    eğer (self) {
        // nesnenin başlatma işlemini burada gerçekleştirin
    }
    return self;
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Instantiation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Instantiation <span style="color:#dddddd">ⓘ</span>]</span>

Yukarıdaki örnekte, id dönüş türüne dikkat edin. Bu tür Objective-C'de "herhangi bir nesneye işaretçi" anlamına gelir (Dinamik yazım bölümüne bakın).

initializer kalıbı, init yöntemi başlatma işlemini gerçekleştirmeden önce nesnenin üst sınıfı tarafından düzgün bir şekilde başlatıldığından emin olmak için kullanılır. Aşağıdaki eylemleri gerçekleştirir:

  1. self = [super init]
    Üst sınıf örneğine bir init mesajı gönderir ve sonucu self'e (geçerli nesnenin işaretçisi) atar.
  2. eğer (self)
    Herhangi bir ilklendirme gerçekleştirmeden önce döndürülen nesne işaretçisinin geçerli olup olmadığını kontrol eder.
  3. return self
    Çağırana self'in değerini döndürür.

Geçerli olmayan bir nesne işaretçisi nil değerine sahiptir; "if" gibi koşullu ifadeler nil'e null işaretçisi gibi davranır, bu nedenle [super init] nil döndürürse başlatma kodu yürütülmez. Başlatma işleminde bir hata varsa, init yöntemi self'e bir "release" mesajı göndermek de dahil olmak üzere gerekli temizlikleri yapmalı ve başlatmanın başarısız olduğunu belirtmek için nil değerini döndürmelidir. Bu tür hatalar için herhangi bir kontrol, nesnenin yok edilmesinin doğru şekilde yapılmasını sağlamak için yalnızca üst sınıf başlatma çağrısı yapıldıktan sonra gerçekleştirilmelidir.

Bir sınıfın birden fazla ilklendirme yöntemi varsa, bunlardan yalnızca birinin ("belirlenmiş ilklendirici") bu kalıbı izlemesi gerekir; diğerleri üst sınıf ilklendiricisi yerine belirlenmiş ilklendiriciyi çağırmalıdır.

Protokoller

Diğer programlama dillerinde bunlara "arayüzler" denir.

Objective-C, NeXT'de protokollerin tanıtılması yoluyla spesifikasyonun çoklu kalıtımı kavramını tanıtmak için genişletildi, ancak uygulama değil. Bu, C++'da soyut çoklu kalıtımlı temel sınıf olarak ya da (Java ve C#'da olduğu gibi) bir "arayüz" olarak elde edilebilen bir modeldir. Objective-C, gayri resmi protokoller olarak adlandırılan geçici protokollerden ve resmi protokoller olarak adlandırılan derleyici tarafından zorlanan protokollerden yararlanır.

Gayri resmi protokol, bir sınıfın uygulamayı seçebileceği yöntemlerin bir listesidir. Dilde bulunmadığı için dokümantasyonda belirtilmiştir. Gayri resmi protokoller NSObject üzerinde bir kategori (aşağıya bakınız) olarak uygulanır ve genellikle uygulandığında bir sınıfın davranışını değiştirebilen isteğe bağlı yöntemler içerir. Örneğin, bir metin alanı sınıfı, kullanıcı tarafından yazılan metnin otomatik olarak tamamlanmasını gerçekleştirmek için isteğe bağlı bir yöntemle gayri resmi bir protokol uygulayan bir temsilciye sahip olabilir. Metin alanı, temsilcinin bu yöntemi uygulayıp uygulamadığını (yansıtma yoluyla) keşfeder ve uyguluyorsa, otomatik tamamlama özelliğini desteklemek için temsilcinin yöntemini çağırır.

Resmi bir protokol Java, C# ve Ada 2005'teki bir arayüze benzer. Herhangi bir sınıfın uygulamak için kendini beyan edebileceği yöntemlerin bir listesidir. Objective-C'nin 2.0'dan önceki sürümleri, bir sınıfın benimsediğini beyan ettiği bir protokoldeki tüm yöntemleri uygulamasını gerektirir; sınıf beyan ettiği protokollerdeki her yöntemi uygulamazsa derleyici bir hata verir. Objective-C 2.0, bir protokoldeki belirli yöntemleri isteğe bağlı olarak işaretleme desteği ekledi ve derleyici isteğe bağlı yöntemlerin uygulanmasını zorlamayacaktır.

Bir sınıfın bu protokole uygun olduğunun söylenebilmesi için bu protokolü uyguladığının beyan edilmesi gerekir. Bu çalışma zamanında tespit edilebilir. Resmi protokoller herhangi bir uygulama sağlayamazlar; sadece protokole uyan sınıfların uygulama sağlayacağını arayanlara garanti ederler. NeXT/Apple kütüphanesinde protokoller, uzak bir sistemde çalışan bir nesnenin yeteneklerini temsil etmek için Dağıtılmış Nesneler sistemi tarafından sıklıkla kullanılır.

Sözdizimi

@protocol NSLocking
- (void)lock;
- (void)unlock;
@end <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Protocols&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Protocols <span style="color:#dddddd">ⓘ</span>]</span>

soyut bir kilitleme fikri olduğunu belirtir. Sınıf tanımında protokolün uygulandığı belirtilerek,

@interface NSLock : NSObject <NSLocking>
// ...
@end <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Protocols&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Protocols <span style="color:#dddddd">ⓘ</span>]</span>

NSLock örnekleri, iki örnek yöntemi için bir uygulama sağlayacaklarını iddia eder.

Dinamik yazım

Smalltalk gibi Objective-C de dinamik yazım kullanabilir: bir nesneye arayüzünde belirtilmeyen bir mesaj gönderilebilir. Bu, bir nesnenin bir mesajı "yakalamasına" ve mesajı, mesaja uygun şekilde yanıt verebilecek farklı bir nesneye göndermesine veya aynı şekilde mesajı başka bir nesneye göndermesine izin verdiği için daha fazla esneklik sağlayabilir. Bu davranış mesaj iletme veya temsilci atama olarak bilinir (aşağıya bakınız). Alternatif olarak, mesajın iletilememesi durumunda bir hata işleyici kullanılabilir. Bir nesne bir mesajı iletmez, yanıt vermez veya bir hatayı işlemezse, sistem bir çalışma zamanı istisnası oluşturur. Mesajlar nil'e (null nesne işaretçisi) gönderilirse, derleyici seçeneklerine bağlı olarak sessizce yok sayılır veya genel bir istisna oluşturur.

Statik tipleme bilgileri de isteğe bağlı olarak değişkenlere eklenebilir. Bu bilgi daha sonra derleme zamanında kontrol edilir. Aşağıdaki dört deyimde, giderek daha spesifik tür bilgileri sağlanmaktadır. Deyimler çalışma zamanında eşdeğerdir, ancak fazladan bilgi, aktarılan argümanın belirtilen türle eşleşmemesi durumunda derleyicinin programcıyı uyarmasını sağlar.

- (void)setMyValue:(id)foo;

Yukarıdaki ifadede, foo herhangi bir sınıftan olabilir.

- (void)setMyValue:(id<NSCopying>)foo;

Yukarıdaki ifadede, foo NSCopying protokolüne uyan herhangi bir sınıfın örneği olabilir.

- (void)setMyValue:(NSNumber *)foo;

Yukarıdaki ifadede, foo NSNumber sınıfının bir örneği olmalıdır.

- (void)setMyValue:(NSNumber<NSCopying> *)foo;

Yukarıdaki ifadede, foo NSNumber sınıfının bir örneği olmalıdır ve NSCopying protokolüne uygun olmalıdır.

Objective-C'de, tüm nesneler işaretçi olarak temsil edilir ve statik başlatmaya izin verilmez. En basit nesne, id'nin (objc_obj *) işaret ettiği türdür ve yalnızca sınıfını tanımlayan bir isa işaretçisine sahiptir. C'deki values ve structs gibi diğer türler, nesne sisteminin bir parçası olmadıkları için değişmezler. Bu karar, struct ve sınıfların birleşik olduğu C++ nesne modelinden farklıdır.

Yönlendirme

Objective-C, yanıt veremeyecek bir nesneye mesaj gönderilmesine izin verir. Bir nesne, yanıt vermek ya da basitçe mesajı bırakmak yerine, mesajı yanıt verebilecek bir nesneye iletebilir. İletme, gözlemci kalıbı veya proxy kalıbı gibi belirli tasarım kalıplarının uygulanmasını basitleştirmek için kullanılabilir.

Objective-C çalışma zamanı Object'te bir çift yöntem belirtir

  • yönlendirme yöntemleri:
    - (retval_t)forward:(SEL)sel args:(arglist_t)args; // GCC ile
    - (id)forward:(SEL)sel args:(marg_list)args; // NeXT/Apple sistemleri ile
  • eylem yöntemleri:
    - (retval_t)performv:(SEL)sel args:(arglist_t)args; // GCC ile
    - (id)performv:(SEL)sel args:(marg_list)args; // NeXT/Apple sistemleri ile <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Forwarding&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Forwarding <span style="color:#dddddd">ⓘ</span>]</span>

Yönlendirmeyi uygulamak isteyen bir nesnenin, yönlendirme davranışını tanımlamak için yalnızca yönlendirme yöntemini yeni bir yöntemle geçersiz kılması gerekir. Bu yöntem yalnızca seçici ve argümanlara dayalı bir eylem gerçekleştirdiğinden, performv:: eylem yönteminin geçersiz kılınmasına gerek yoktur. Objective-C'deki mesajların türü olan SEL türüne dikkat edin.

Not: Objective-C'nin yaygın olarak kullanılan çerçeveleri olan OpenStep, Cocoa ve GNUstep'te Object sınıfı kullanılmaz. İletim yapmak için NSObject sınıfının -(void)forwardInvocation:(NSInvocation *)anInvocation yöntemi kullanılır.

Örnek

İşte iletimin temellerini gösteren bir program örneği.

Forwarder.h
#import <objc/Object.h> <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

@interface Forwarder : Object {
  id recipient; // Mesajı iletmek istediğimiz nesne.
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

// Accessor yöntemleri.
- (id)recipient;
- (id)setRecipient:(id)_recipient;
@end

Forwarder.m
#import "Forwarder.h" <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

@implementation Forwarder
- (retval_t)forward:(SEL)sel args:(arglist_t)args {
  /*
  * Alıcının mesaja gerçekten yanıt verip vermediğini kontrol edin.
  * Bu istenilen bir durum olabilir ya da olmayabilir, örneğin bir alıcı
  * mesaja yanıt vermezse, iletme işlemi gerçekleştirebilir
  * kendisi.
  */
  if ([recipient respondsToSelector:sel]) {
    return [recipient performv:sel args:args];
  } else {
    return [self error: "Alıcı yanıt vermiyor"];
  }
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

- (id)setRecipient:(id)_recipient {
  [alıcı otomatik serbest bırak];
  recipient = [_recipient retain];
  return self;
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

- (id)alıcı {
  alıcıyı döndür;
}
@end

Recipient.h
#import <objc/Object.h> <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

// Basit bir Alıcı nesnesi.
@interface Recipient : Nesne
- (id)hello;
@end

Recipient.m
#import "Recipient.h" <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

@implementation Alıcı <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

- (id)hello {
  printf("Alıcı merhaba diyor!\n"); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

  return self;
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

@end

main.m
#import "Forwarder.h"
#import "Recipient.h" <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

int main(void) {
  Forwarder *forwarder = [Forwarder new];
  Alıcı *alıcı = [Alıcı yeni]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

  [forwarder setRecipient:recipient]; // Alıcıyı ayarlayın.
  /*
  * İleticinin bir merhaba mesajına yanıt vermediğini gözlemleyin! Verecek
  * iletilecektir. Tanınmayan tüm yöntemler şu adrese iletilecektir
  * alıcı
  * (alıcı bunlara yanıt verirse, İleticide yazıldığı gibi)
  */
  [iletici merhaba]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

  [alıcı serbest bırak];
  [iletici serbest bırak]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example <span style="color:#dddddd">ⓘ</span>]</span>

  return 0;
}

Kategoriler

Objective-C'nin tasarımı sırasında temel kaygılardan biri büyük kod tabanlarının sürdürülebilirliğiydi. Yapılandırılmış programlama dünyasından edinilen deneyimler, kodu geliştirmenin ana yollarından birinin onu daha küçük parçalara ayırmak olduğunu göstermişti. Objective-C bu sürece yardımcı olmak için Smalltalk uygulamalarından kategori kavramını ödünç aldı ve genişletti.

Ayrıca, bir kategori içindeki yöntemler çalışma zamanında bir sınıfa eklenir. Böylece kategoriler, programcının mevcut bir sınıfa - açık bir sınıfa - o sınıfı yeniden derlemesine veya hatta kaynak koduna erişmesine gerek kalmadan yöntemler eklemesine izin verir. Örneğin, bir sistem String uygulamasında bir yazım denetleyicisi içermiyorsa, String kaynak kodunu değiştirmeden eklenebilir.

Kategorilerdeki yöntemler, program çalıştırıldığında bir sınıftaki yöntemlerden ayırt edilemez hale gelir. Bir kategori, özel değişkenler de dahil olmak üzere sınıf içindeki tüm örnek değişkenlere tam erişime sahiptir.

Bir kategori, bir sınıftaki mevcut bir yöntemle aynı yöntem imzasına sahip bir yöntem bildirirse, kategorinin yöntemi benimsenir. Böylece kategoriler yalnızca bir sınıfa yöntem eklemekle kalmaz, aynı zamanda mevcut yöntemleri de değiştirebilir. Bu özellik, yöntemlerini yeniden yazarak diğer sınıflardaki hataları düzeltmek veya bir program içinde bir sınıfın davranışında genel bir değişikliğe neden olmak için kullanılabilir. İki kategorinin aynı isimde ancak farklı yöntem imzalarına sahip yöntemleri varsa, hangi kategorinin yönteminin benimsendiği tanımlanamaz.

Diğer diller bu özelliği çeşitli şekillerde eklemeye çalışmıştır. TOM, Objective-C sistemini bir adım daha ileri götürmüş ve değişkenlerin de eklenmesine izin vermiştir. Diğer diller bunun yerine prototip tabanlı çözümler kullanmışlardır, bunlardan en dikkat çekeni Self'tir.

C# ve Visual Basic.NET dilleri, uzantı yöntemleri şeklinde yüzeysel olarak benzer işlevler uygular, ancak bunlar sınıfın özel değişkenlerine erişimden yoksundur. Ruby ve diğer bazı dinamik programlama dilleri bu tekniği "maymun yamalama" olarak adlandırır.

Logtalk, Objective-C kategorilerinin işlevselliğini üstlenen bir kategori kavramı (birinci sınıf varlıklar olarak) uygular (Logtalk kategorileri, örneğin yeni sınıflar veya prototipler tanımlanırken ince taneli kompozisyon birimleri olarak da kullanılabilir; özellikle, bir Logtalk kategorisi herhangi bir sayıda sınıf ve prototip tarafından sanal olarak içe aktarılabilir).

Kategorilerin örnek kullanımı

Bu örnek, önce yalnızca erişimci yöntemlerin uygulandığı bir temel sınıf tanımlayarak ve temel sınıfı genişleten Aritmetik ve Görüntüleme adlı iki kategori ekleyerek bir Integer sınıfı oluşturur. Kategoriler temel sınıfın özel veri üyelerine erişebilse de, kategorileri temel sınıftan daha bağımsız tutmaya yardımcı olan erişimci yöntemleri aracılığıyla bu özel veri üyelerine erişmek genellikle iyi bir uygulamadır. Bu tür erişimcileri uygulamak kategorilerin tipik bir kullanımıdır. Bir diğeri de kategorileri temel sınıfa yöntem eklemek için kullanmaktır. Ancak, maymun yamalama olarak da bilinen alt sınıf geçersiz kılma için kategorileri kullanmak iyi bir uygulama olarak kabul edilmez. Resmi olmayan protokoller temel NSObject sınıfında bir kategori olarak uygulanır. Kural olarak, temel sınıfları genişleten kategorileri içeren dosyalar BaseClass+ExtensionClass.h adını alacaktır.

Integer.h
#import <objc/Object.h> <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

@interface Integer : Object {
  int tamsayı;
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

- (int)integer;
- (id)integer:(int)_integer;
@end

Integer.m
#import "Integer.h" <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

@implementation Integer
- (int) tamsayı {
  integer döndür;
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

- (id) integer: (int) _integer {
  integer = _integer;
  return self;
}
@end

Integer+Aritmetik.h
#import "Integer.h" <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

@interface Integer (Aritmetik)
- (id) add: (Integer *) addend;
- (id) sub: (Integer *) subtrahend;
@end

Integer+Aritmetik.m
#import "Integer+Arithmetic.h" <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

@implementation Integer (Aritmetik)
- (id) add: (Integer *) addend {
  return [self integer: [self tamsayı] + [addend tamsayı]];
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

- (id) sub: (Integer *) subtrahend {
  return [self integer: [self tamsayı] - [subtrahend tamsayı]];
}
@end

Integer+Display.h
#import "Integer.h" <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

@interface Integer (Display)
- (id) showstars;
- (id) showint;
@end

Integer+Display.m
# import "Integer+Display.h" <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

@implementation Integer (Display)
- (id) showstars {
  int i, x = [self integer];
  for (i = 0; i < x; i++) {
    printf("*");
  }
  printf("\n"); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

  return self;
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

- (id) showint {
  printf("%d\n", [self integer]); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

  self döndür;
}
@end

main.m
#import "Integer.h"
#import "Integer+Arithmetic.h"
#import "Integer+Display.h" <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

int main(void) {
  Integer *num1 = [Integer new], *num2 = [Integer new];
  int x; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

  printf("Bir tamsayı girin: ");
  scanf("%d", &x); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

  [num1 tamsayı:x];
  [num1 showstars]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

  printf("Bir tamsayı girin: ");
  scanf("%d", &x); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

  [num2 tamsayı:x];
  [num2 showstars]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

  [num1 add:num2];
  [num1 showint]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Example use of categories&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Example_use_of_categories <span style="color:#dddddd">ⓘ</span>]</span>

  return 0;
}

Poz verme

Objective-C, bir sınıfın bir program içinde başka bir sınıfın yerini almasına izin verir. Değiştiren sınıfın hedef sınıf olarak "poz verdiği" söylenir.

Sınıf pozu Mac OS X v10.5 ile kullanımdan kaldırılmıştır ve 64 bit çalışma zamanında kullanılamaz. Benzer işlevsellik, bir yöntemin uygulamasını aynı imzaya sahip başka bir yöntemle değiştiren kategorilerdeki yöntem swizzling kullanılarak da elde edilebilir.

Hala poz vermeyi destekleyen sürümler için, hedef sınıfa gönderilen tüm mesajlar bunun yerine poz veren sınıf tarafından alınır. Birkaç kısıtlama vardır:

  • Bir sınıf yalnızca doğrudan veya dolaylı üst sınıflarından biri olarak poz verebilir.
  • Poz veren sınıf, hedef sınıfta bulunmayan herhangi bir yeni örnek değişken tanımlamamalıdır (ancak yöntemleri tanımlayabilir veya geçersiz kılabilir).
  • Hedef sınıf poz vermeden önce herhangi bir mesaj almamış olabilir.

Posing, kategorilere benzer şekilde, mevcut sınıfların global olarak artırılmasına izin verir. Pozlandırma, kategorilerde bulunmayan iki özelliğe izin verir:

  • Poz veren bir sınıf super aracılığıyla geçersiz kılınmış yöntemleri çağırabilir, böylece hedef sınıfın uygulamasını dahil edebilir.
  • Bir poz veren sınıf, kategorilerde tanımlanan yöntemleri geçersiz kılabilir.

Örneğin,

@interface CustomNSApplication : NSApplication
@end <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Posing&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Posing <span style="color:#dddddd">ⓘ</span>]</span>

@implementation CustomNSApplication
- (void) setMainMenu: (NSMenu*) menu {
  // menü ile bir şeyler yap
}
@end <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Posing&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Posing <span style="color:#dddddd">ⓘ</span>]</span>

class_poseAs ([CustomNSApplication class], [NSApplication class]);

Bu, setMainMenu'nün NSApplication'a her çağrılmasını engeller.

#import

C dilinde, #include ön derleme yönergesi her zaman bir dosyanın içeriğinin o noktada kaynağa eklenmesine neden olur. Objective-C'de #import yönergesi vardır, ancak her dosya derleme birimi başına yalnızca bir kez dahil edilir ve include korumalarına olan ihtiyacı ortadan kaldırır.

Linux gcc derleme

// DOSYA: hello.m
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
    /* Objective-C'deki ilk programım */
    NSLog(@"Merhaba, Dünya! \n");
    return 0;
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Linux gcc compilation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Linux_gcc_compilation <span style="color:#dddddd">ⓘ</span>]</span>

# gcc ve MinGW Derleyicisi için Derleme Komut Satırı:
$ gcc \
    $(gnustep-config --objc-flags) \
    -o merhaba \
    merhaba.m \
    -L /GNUstep/System/Library/Libraries \
    -lobjc \
    -lgnustep-base <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Linux gcc compilation&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Linux_gcc_compilation <span style="color:#dddddd">ⓘ</span>]</span>

$ ./hello

Diğer özellikler

Objective-C'nin özellikleri programlama sorunlarına esnek ve genellikle kolay çözümler sağlar.

  • Yöntemleri diğer nesnelere devretme ve uzaktan çağırma, kategoriler ve mesaj iletme kullanılarak kolayca uygulanabilir.
  • Çalkalama isa işaretçi, sınıfların çalışma zamanında değişmesine izin verir. Tipik olarak, serbest bırakılan nesnelerin, tek amacı birisi onları çağırdığında bir hata bildirmek olan zombi nesnelere dönüştürüldüğü hata ayıklama için kullanılır. Swizzling ayrıca Enterprise Objects Framework'te veritabanı hataları oluşturmak için de kullanılmıştır. Swizzling bugün Apple'ın Foundation Framework'ü tarafından Anahtar-Değer Gözlemleme'yi uygulamak için kullanılmaktadır.

Dil varyantları

Objective-C++

Objective-C++, C++ ve Objective-C sözdiziminin bir kombinasyonunu kullanan kaynak dosyalarını derleyebilen GNU Derleyici Koleksiyonu ve Clang'ın ön ucu tarafından kabul edilen bir dil çeşididir. Objective-C++, Objective-C'nin C'ye eklediği uzantıları C++'ya ekler. Çeşitli dil özelliklerinin arkasındaki anlamları birleştirmek için hiçbir şey yapılmadığından, belirli kısıtlamalar geçerlidir:

  • Bir C++ sınıfı bir Objective-C sınıfından türetilemez ve bunun tersi de geçerlidir.
  • C++ isim alanları bir Objective-C bildiriminin içinde bildirilemez.
  • Objective-C bildirimleri C++ ad alanı içinde değil, yalnızca global kapsamda görünebilir
  • Objective-C sınıfları, varsayılan bir kurucusu olmayan veya bir veya daha fazla sanal yöntemi olan C++ sınıflarının örnek değişkenlerine sahip olamaz, ancak C++ nesnelerine işaretçiler kısıtlama olmaksızın örnek değişkenleri olarak kullanılabilir (bunları -init yönteminde new ile tahsis edin).
  • C++ "by value" semantiği, sadece işaretçiler aracılığıyla erişilebilen Objective-C nesnelerine uygulanamaz.
  • Bir Objective-C bildirimi bir C++ şablon bildirimi içinde olamaz ve bunun tersi de geçerlidir. Ancak, Objective-C türleri (örn, Sınıfadı *) C++ şablon parametreleri olarak kullanılabilir.
  • Objective-C ve C++ istisna işleme farklıdır; her birinin işleyicileri diğer türün istisnalarını işleyemez. Sonuç olarak, nesne yıkıcıları çalıştırılmaz. Objective-C istisnaları ya tamamen (Apple çalışma zamanı) ya da Objective-C++ kütüphanesi bağlandığında (GNUstep libobjc2) kısmen C++ istisnaları ile değiştirildiğinden, bu durum son "Objective-C 2.0" çalışma zamanlarında hafifletilmiştir.
  • Objective-C blokları ve C++11 lambdaları farklı varlıklardır. Bununla birlikte, macOS'ta bir blok beklenen bir lambda geçerken şeffaf bir şekilde bir blok oluşturulur.

Objective-C 2.0

2006 Dünya Çapında Geliştiriciler Konferansı'nda Apple, Objective-C dilinin "modern çöp toplama, sözdizimi geliştirmeleri, çalışma zamanı performans iyileştirmeleri ve 64-bit desteği" içerecek şekilde revize edildiği "Objective-C 2.0" sürümünü duyurdu. Ekim 2007'de piyasaya sürülen Mac OS X v10.5, bir Objective-C 2.0 derleyicisi içeriyordu. GCC 4.6, bildirilen ve sentezlenen özellikler, nokta sözdizimi, hızlı numaralandırma, isteğe bağlı protokol yöntemleri, yöntem/protokol/sınıf nitelikleri, sınıf uzantıları ve yeni bir GNU Objective-C çalışma zamanı API'si gibi birçok yeni Objective-C özelliğini destekler.

Objective-C 2.0 adlandırması, NeXT için son Objective-C sürümü "objc4" olduğundan, dilin sürümlendirme sisteminde bir kırılmayı temsil etmektedir. Bu proje adı, Mac OS X Leopard'daki (10.5) eski Objective-C çalışma zamanı kaynak kodunun son sürümünde korunmuştur.

Çöp toplama

Objective-C 2.0, isteğe bağlı muhafazakar, nesilsel bir çöp toplayıcı sağladı. Geriye dönük uyumlu modda çalıştırıldığında, çalışma zamanı "tutma" ve "bırakma" gibi referans sayma işlemlerini no-ops'a dönüştürdü. Çöp toplama etkinleştirildiğinde tüm nesneler çöp toplamaya tabiydi. Normal C işaretçileri "__strong" ile nitelenerek altta yatan yazma bariyeri derleyici kesmelerini de tetikleyebilir ve böylece çöp toplamaya katılabilir. "__weak" olarak işaretlenen işaretçilerin nesne (ya da daha basitçe GC belleği) toplandığında sıfıra ayarlanmasını sağlayan bir sıfırlama zayıf alt sistemi de sağlanmıştır. Objective-C 2.0'ın iOS uygulamasında çöp toplayıcı mevcut değildir. Objective-C'de çöp toplama, düşük öncelikli bir arka plan iş parçacığı üzerinde çalışır ve kullanıcı deneyimini duyarlı tutmak amacıyla kullanıcı olaylarında durabilir.

Çöp toplama Mac OS X v10.8'de Otomatik Referans Sayma (ARC) lehine kullanımdan kaldırılmıştır. ARM64 üzerinde çalışan iOS 7'deki Objective-C, referans sayısını etiketlenmiş işaretçilerin bir biçimi olarak saklamak için 64 bitlik bir kelimenin 19 bitini kullanır.

Özellikler

Objective-C 2.0, örnek değişkenleri özellik olarak bildirmek için yeni bir sözdizimi sunmakta ve erişim yöntemlerinin oluşturulmasını yapılandırmak için isteğe bağlı nitelikler içermektedir. Özellikler, bir anlamda genel örnek değişkenleridir; yani, bir örnek değişkenini özellik olarak bildirmek, harici sınıflara bu özelliğe erişim (muhtemelen sınırlı, örneğin yalnızca okuma) sağlar. Bir özellik "salt okunur" olarak bildirilebilir ve atama, kopyalama veya saklama gibi depolama semantikleri ile sağlanabilir. Varsayılan olarak, özellikler atomik olarak kabul edilir, bu da aynı anda birden fazla iş parçacığının bunlara erişmesini engelleyen bir kilitle sonuçlanır. Bir özellik atomik olmayan olarak bildirilebilir, bu da bu kilidi kaldırır.

@interface Person : NSObject {
@public
  NSString *name;
@özel
  int yaş;
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Properties&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Properties <span style="color:#dddddd">ⓘ</span>]</span>

@property(copy) NSString *name;
@property(readonly) int age; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Properties&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Properties <span style="color:#dddddd">ⓘ</span>]</span>

- (id)initWithAge:(int)age;
@end

Özellikler, özellik bildirimine göre getter (ve salt okunur değilse setter) yöntemlerini oluşturan @synthesize anahtar sözcüğü aracılığıyla uygulanır. Alternatif olarak, getter ve setter yöntemleri açıkça uygulanmalıdır veya erişimci yöntemlerinin başka yollarla sağlanacağını belirtmek için @dynamic anahtar sözcüğü kullanılabilir. clang 3.1 veya üstü kullanılarak derlendiğinde, @dynamic ile açıkça bildirilmemiş, readonly olarak işaretlenmiş veya kullanıcı tarafından tam olarak uygulanmış getter ve setter'a sahip tüm özellikler otomatik olarak örtük olarak @synthesize'lanacaktır.

@implementation Kişi
@synthesize name; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Properties&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Properties <span style="color:#dddddd">ⓘ</span>]</span>

- (id)initWithAge:(int)initAge {
  self = [super init];
  eğer (self) {
    // NOT: doğrudan örnek değişken ataması, özellik ayarlayıcı değil
    age = initAge;
  }
  return self;
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Properties&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Properties <span style="color:#dddddd">ⓘ</span>]</span>

- (int)yaş {
  yaşı döndür;
}
@end

Özelliklere geleneksel mesaj geçişi sözdizimi, nokta gösterimi veya Anahtar-Değer Kodlamasında "valueForKey:"/"setValue:forKey:" yöntemleri aracılığıyla isimle erişilebilir.

Person *aPerson = [[Person alloc] initWithAge:53];
aPerson.name = @"Steve"; // NOT: nokta gösterimi, sentezlenmiş setter kullanır,
                         // [aPerson setName: @"Steve"] ile eşdeğerdir;
NSLog(@"Mesaja göre erişim (%@), nokta gösterimi(%@), özellik adı(%@) ve "
       "doğrudan örnek değişken erişimi (% @) ",
              [aKişi adı],
      aPerson.name, [aPerson valueForKey:@"name"], aPerson -> name); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Properties&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Properties <span style="color:#dddddd">ⓘ</span>]</span>

Bir örnek metodu içinde özellik erişimcilerini çağırmak üzere nokta gösterimini kullanmak için "self" anahtar sözcüğü kullanılmalıdır:

- (void)introduceMyselfWithProperties:(BOOL)useGetter {
  NSLog(@"Merhaba, benim adım %@.", (useGetter ? self.name : name));
  // NOT: getter vs. ivar erişimi
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Properties&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Properties <span style="color:#dddddd">ⓘ</span>]</span>

Bir sınıfın veya protokolün özellikleri dinamik olarak iç gözlemlenebilir.

int i;
int propertyCount = 0;
objc_property_t *propertyList =
    class_copyPropertyList([aPerson class], &propertyCount); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Properties&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Properties <span style="color:#dddddd">ⓘ</span>]</span>

for (i = 0; i < propertyCount; i++) {
  objc_property_t *thisProperty = propertyList + i;
  const char *propertyName = property_getName(*thisProperty);
  NSLog(@"Kişinin bir özelliği var: '%s'", propertyName);
}

Kırılgan olmayan örnek değişkenler

Objective-C 2.0, çalışma zamanı tarafından desteklenen yerlerde (yani 64 bit macOS ve tüm iOS için kod oluştururken) kırılgan olmayan örnek değişkenleri sağlar. Modern çalışma zamanı altında, örnek değişken erişimine ekstra bir dolaylılık katmanı eklenerek dinamik bağlayıcının çalışma zamanında örnek düzenini ayarlamasına izin verilir. Bu özellik Objective-C kodunda iki önemli iyileştirme sağlar:

  • Kırılgan ikili arayüz sorununu ortadan kaldırır; üst sınıflar ikili uyumluluğu etkilemeden boyutlarını değiştirebilir.
  • Özellikler için destek sağlayan örnek değişkenlerinin, sınıfın arayüzünde bildirilmeden çalışma zamanında sentezlenmesine olanak tanır.

Hızlı numaralandırma

Objective-C 2.0, bir koleksiyonda yineleme yapmak için bir NSEnumerator nesnesi veya indeksler kullanmak yerine, hızlı numaralandırma sözdizimini sunar. Objective-C 2.0'da, aşağıdaki döngüler işlevsel olarak eşdeğerdir, ancak farklı performans özelliklerine sahiptir.

// NSEnumerator Kullanma
NSEnumerator *enumerator = [thePeople objectEnumerator];
Kişi *p; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Fast enumeration&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Fast_enumeration <span style="color:#dddddd">ⓘ</span>]</span>

while ((p = [enumerator nextObject]) != nil) {
  NSLog(@"%@ is %i years old.", [p name], [p age]);
}

// Dizinleri kullanma
for (int i = 0; i < [thePeople count]; i++) {
  Kişi *p = [thePeople objectAtIndex:i];
  NSLog(@"%@ %i yaşında.", [p adı], [p yaşı]);
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Fast enumeration&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Fast_enumeration <span style="color:#dddddd">ⓘ</span>]</span>
// Hızlı numaralandırma kullanarak
for (Person *p in thePeople) {
  NSLog(@"%@ is %i years old.", [p name], [p age]);
} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Fast enumeration&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Fast_enumeration <span style="color:#dddddd">ⓘ</span>]</span>

Hızlı numaralandırma standart numaralandırmaya göre daha verimli kod üretir çünkü nesneler üzerinde numaralandırma yapmak için yapılan yöntem çağrıları NSFastEnumeration protokolü kullanılarak işaretçi aritmetiği ile değiştirilir.

Sınıf uzantıları

Bir sınıf uzantısı, kategori adı olmayan bir kategori bildirimiyle aynı sözdizimine sahiptir ve içinde bildirilen yöntemler ve özellikler doğrudan ana sınıfa eklenir. Çoğunlukla, genel başlıklarda reklamını yapmadan bir sınıfa yöntem eklemek için bir kategoriye alternatif olarak kullanılır; sınıf uzantıları için derleyicinin özel olarak bildirilen tüm yöntemlerin gerçekten uygulanıp uygulanmadığını kontrol etmesi avantajı vardır.

Cocoa geliştirme için çıkarımlar

macOS için geliştirilen ve Objective-C 2.0 için yukarıdaki iyileştirmelerden yararlanan tüm Objective-C uygulamaları, 10.5 (Leopard) öncesi tüm işletim sistemleriyle uyumlu değildir. Hızlı numaralandırma, standart numaralandırma ile tam olarak aynı ikili dosyaları oluşturmadığından, kullanımı Mac OS X sürüm 10.4 veya önceki sürümlerde uygulamanın çökmesine neden olur.

Bloklar

Bloklar, Objective-C (ve C ve C++) için kapanışlar oluşturmak için özel sözdizimi kullanan standart olmayan bir uzantıdır. Bloklar yalnızca Mac OS X 10.6 "Snow Leopard" veya üstü, iOS 4 veya üstü ve libobjc2 1.7 ile GNUstep'te ve clang 3.1 veya üstü ile derlemede desteklenir.

#include <stdio.h>
#include <Block.h>
typedef int (^IntBlock)(); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Blocks&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Blocks <span style="color:#dddddd">ⓘ</span>]</span>

IntBlock MakeCounter(int start, int increment) {
  __block int i = start; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Blocks&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Blocks <span style="color:#dddddd">ⓘ</span>]</span>

  return Block_copy( ^ {
    int ret = i;
    i += artış;
    return ret;
  }); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Blocks&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Blocks <span style="color:#dddddd">ⓘ</span>]</span>

} <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Blocks&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Blocks <span style="color:#dddddd">ⓘ</span>]</span>

int main(void) {
  IntBlock mycounter = MakeCounter(5, 2);
  printf("İlk çağrı: %d\n", mycounter());
  printf("İkinci çağrı: %d\n", mycounter());
  printf("Üçüncü çağrı: %d\n", mycounter()); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Blocks&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Blocks <span style="color:#dddddd">ⓘ</span>]</span>

  /* kopyalandığı için serbest bırakılması da gerekir */
  Block_release(mycounter); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Blocks&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Blocks <span style="color:#dddddd">ⓘ</span>]</span>

  return 0;
}
/* Çıktı:
  İlk çağrı: 5
  İkinci arama: 7
  Üçüncü arama: 9
*/

Modern Objective-C

Apple zaman içinde Objective 2.0'a bazı ek özellikler eklemiştir. Eklemeler yalnızca "Apple LLVM derleyicisi", yani dilin clang ön ucu için geçerlidir. Kafa karıştırıcı bir şekilde, Apple tarafından kullanılan versiyonlama LLVM upstream'inkinden farklıdır; açık kaynak LLVM versiyon numaralarına çeviri için Xcode § Toolchain versions bölümüne bakın.

Otomatik Referans Sayma

Otomatik Referans Sayma (ARC), programcıların tutma ve serbest bırakma kullanarak tutma sayılarını manuel olarak yönetme ihtiyacını ortadan kaldıran bir derleme zamanı özelliğidir. Çalışma zamanında gerçekleşen çöp toplamanın aksine ARC, tutma sayılarını yöneten ayrı bir işlemin ek yükünü ortadan kaldırır. ARC ve manuel bellek yönetimi birbirini dışlamaz; programcılar ARC'yi tek tek kod dosyaları için devre dışı bırakarak ARC özellikli projelerde ARC olmayan kod kullanmaya devam edebilirler. Xcode ayrıca bir projeyi otomatik olarak ARC'ye yükseltmeyi de deneyebilir.

ARC, LLVM 3.0'da tanıtılmıştır. Bu, Xcode 4.2 (2011) veya Apple LLVM derleyicisi 3.0 anlamına gelir.

Literals

NeXT ve Apple Obj-C çalışma zamanları, @"a new string" sözdizimini kullanarak veya Boolean değerlerine sahip NSNumber için CoreFoundation sabitleri kCFBooleanTrue ve kCFBooleanFalse'a bırakarak yeni dizeler oluşturmak için uzun zamandır kısa biçimli bir yol içermektedir. Bu biçimi kullanmak, programcıyı belirli işlemleri yaparken daha uzun initWithString veya benzer yöntemleri kullanmak zorunda kalmaktan kurtarır.

Apple LLVM derleyicisi 4.0 (Xcode 4.4) veya sonraki sürümleri kullanıldığında, diziler, sözlükler ve sayılar (NSArray, NSDictionary, NSNumber sınıfları) yöntemler yerine değişmez sözdizimi kullanılarak da oluşturulabilir. (Apple LLVM derleyicisi 4.0, açık kaynak LLVM ve Clang 3.1'e çevrilir).

Değişmezler olmadan örnek:

NSArray *myArray = [NSArray arrayWithObjects:object1,object2,object3,nil];
NSDictionary *myDictionary1 = [NSDictionary dictionaryWithObject:someObject forKey:@"key"];
NSDictionary *myDictionary2 = [NSDictionary dictionaryWithObjectsAndKeys:object1, key1, object2, key2, nil];
NSNumber *myNumber = [NSNumber numberWithInt:myInt];
NSNumber *mySumNumber= [NSNumber numberWithInt:(2 + 3)];
NSNumber *myBoolNumber = [NSNumber numberWithBool:YES]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Literals&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Literals <span style="color:#dddddd">ⓘ</span>]</span>

Değişmezler ile örnek:

NSArray *myArray = @[ object1, object2, object3 ];
NSDictionary *myDictionary1 = @{ @"key" : someObject };
NSDictionary *myDictionary2 = @{ key1: object1, key2: object2 };
NSNumber *myNumber = @(myInt);
NSNumber *mySumNumber = @(2+3);
NSNumber *myBoolNumber = @YES;
NSNumber *myIntegerNumber = @8; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Literals&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Literals <span style="color:#dddddd">ⓘ</span>]</span>

Ancak, çalıştırılabilir dosyada sabitlere derlenen dize değişmezlerinden farklı olarak, bu değişmezler yukarıdaki yöntem çağrılarına eşdeğer kodlara derlenir. Özellikle, manuel referans sayımlı bellek yönetimi altında, bu nesneler otomatik olarak serbest bırakılır, bu da örneğin fonksiyon-statik değişkenleri veya diğer global türleriyle birlikte kullanıldığında daha fazla dikkat gerektirir.

Alt komut dosyası oluşturma

Apple LLVM derleyicisi 4.0 veya üstü kullanıldığında, diziler ve sözlükler (NSArray ve NSDictionary sınıfları) subscripting kullanılarak manipüle edilebilir. Alt kodlama, dizinlerden (dizi) veya anahtarlardan (sözlük) değer almak için kullanılabilir ve değiştirilebilir nesnelerle, nesneleri dizinlere veya anahtarlara ayarlamak için de kullanılabilir. Kodda, alt kodlama parantez [ ] kullanılarak gösterilir.

Alt simge kullanmadan örnek:

id object1 = [someArray objectAtIndex:0];
id object2 = [someDictionary objectForKey:@"key"];
[someMutableArray replaceObjectAtIndex:0 withObject:object3];
[someMutableDictionary setObject:object4 forKey:@"key"]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Subscripting&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Subscripting <span style="color:#dddddd">ⓘ</span>]</span>

Alt kodlama ile örnek:

id object1 = someArray[0];
id object2 = someDictionary[@"key"];
someMutableArray[0] = object3;
someMutableDictionary[@"key"] = object4; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;Subscripting&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#Subscripting <span style="color:#dddddd">ⓘ</span>]</span>

"Modern" Objective-C sözdizimi (1997)

NeXT'in Apple tarafından satın alınmasından sonra, dili Smalltalk'tan çok Java'ya aşina olan programcılar için daha kabul edilebilir hale getirmek için girişimlerde bulunuldu. Bu girişimlerden biri, o dönemde Objective-C için "Modern Sözdizimi" olarak adlandırılan (mevcut "klasik" sözdiziminin aksine) bir sözdizimi sunmaktı. Davranışta herhangi bir değişiklik yoktu, bu sadece alternatif bir sözdizimiydi. Aşağıdaki gibi bir yöntem çağrısı yazmak yerine

    object = [[MyClass alloc] init];
    [object firstLabel: param1 secondLabel: param2]; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;&quot;Modern&quot; Objective-C syntax (1997)&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#&quot;Modern&quot;_Objective-C_syntax_(1997) <span style="color:#dddddd">ⓘ</span>]</span>

Bunun yerine şu şekilde yazılmıştır

    object = (MyClass.alloc).init;
    object.labels ( param1, param2 ); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;&quot;Modern&quot; Objective-C syntax (1997)&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#&quot;Modern&quot;_Objective-C_syntax_(1997) <span style="color:#dddddd">ⓘ</span>]</span>

Benzer şekilde, bildirimler formdan

    -(void) firstLabel: (int)param1 secondLabel: (int)param2; <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;&quot;Modern&quot; Objective-C syntax (1997)&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#&quot;Modern&quot;_Objective-C_syntax_(1997) <span style="color:#dddddd">ⓘ</span>]</span>

için

    -(void) labels ( int param1, int param2 ); <span title="Kaynak: İngilizce Vikipedi, Bölüm &quot;&quot;Modern&quot; Objective-C syntax (1997)&quot;" class="plainlinks">[https://en.wikipedia.org/wiki/Objective-C#&quot;Modern&quot;_Objective-C_syntax_(1997) <span style="color:#dddddd">ⓘ</span>]</span>

Bu "modern" sözdizimi Objective-C dilinin güncel lehçelerinde artık desteklenmemektedir.

mulle-objc

mulle-objc projesi Objective-C'nin bir başka yeniden uygulamasıdır. Arka uç olarak GCC veya Clang/LLVM derleyicilerini destekler. Sözdizimi, semantik ve ABI uyumluluğu açısından diğer çalışma zamanlarından ayrılır. Linux, FreeBSD ve Windows'u destekler.

Taşınabilir Nesne Derleyicisi

Orijinal Stepstone uygulamasına çeşitli uzantılar ekleyen GCC/NeXT/Apple uygulamasının yanı sıra, Portable Object Compiler adında ücretsiz, açık kaynaklı bir Objective-C uygulaması da mevcuttur. Taşınabilir Nesne Derleyicisi tarafından uygulanan uzantılar kümesi GCC/NeXT/Apple uygulamasından farklıdır; özellikle, Objective-C için Smalltalk benzeri bloklar içerirken, OpenStep ve türevleri ve akrabalarında yaygın olarak kullanılan iki özellik olan protokoller ve kategorilerden yoksundur. Genel olarak POC, dilin evriminde daha eski, NeXT öncesi bir aşamayı temsil eder ve kabaca Brad Cox'un 1991 tarihli kitabına uygundur.

Ayrıca, Cox'un orijinal ICPak101 kütüphanesine dayanan (bu da Smalltalk-80 sınıf kütüphanesinden türemiştir) ve OpenStep FoundationKit'ten oldukça farklı olan ObjectPak adlı bir çalışma zamanı kütüphanesi içerir.

GEOS Objective-C

PC GEOS sistemi GEOS Objective-C veya goc olarak bilinen bir programlama dili kullanıyordu; isim benzerliğine rağmen, iki dil sadece genel konsept ve @ işareti ile ön eklenmiş anahtar kelimelerin kullanımı açısından benzerdir.

Clang

LLVM projesinin bir parçası olan Clang derleyici paketi Objective-C ve diğer dilleri uygular. GCC 4.3 (2008) GPLv3'e geçtikten sonra Apple, değiştirmek için daha fazla yasal güce sahip olduğu bir derleyici olan clang lehine onu terk etti. Sonuç olarak, modern Objective-C dil özelliklerinin çoğu yalnızca Clang tarafından desteklenmektedir.

Apple'ın clang tabanlı "LLVM derleyicisi" için sürümleme şeması, LLVM'nin açık kaynak sürümlemesinden farklıdır. Çeviri için Xcode § Araç Zinciri sürümleri bölümüne bakın

GNU, GNUstep ve WinObjC

GNU projesi uzun zamandır NeXT ve Obj-C programlarını taşıyacak bir platformla ilgilenmektedir. GCC'deki libobjc dizini için ChangeLog, 1998'den önce (GCC 2.95) var olduğunu ve README'nin 1993'te (GCC 2.4) yeniden yazıldığını göstermektedir.

NeXT ön uç kaynak kodu, GCC'nin bir parçası olarak yapıldığı için yayınlandı, türev çalışmalar yapanları bunu yapmaya zorlayan GNU Kamu Lisansı yayınlandı. Apple bu geleneği GCC çatalını 4.2.1'e kadar yayınlayarak sürdürdü ve sonrasında derleyiciyi terk etti. GCC bakımcıları değişiklikleri kabul ettiler, ancak Objective-C 2.0 dili gibi daha yeni özellikleri desteklemek için fazla yatırım yapmadılar.

Yeni dille ilgilenen GNUstep geliştiricileri, 2009 yılında GCC libobjc'yi libobjc2 adlı GCC'den bağımsız bir projeye çatalladılar. Ayrıca yeni dil sözdiziminden yararlanmak için çalışma zamanının Clang ile kullanılmasını sağladılar. GCC aynı zamanda yavaş hareket etti, ancak GCC 4.6.0'da (2011) libobjc'de Objective-C 2.0'a da geçtiler. GNUstep dokümantasyonu, GCC uygulamasının hala bloklar, kırılgan olmayan değişkenler ve daha yeni ARC için destekten yoksun olduğunu göstermektedir.

Microsoft, libobjc2'yi 2015 yılında Evrensel Windows Platformu için iOS köprüsü olan WinObjC'nin bir parçası haline getirdi. Kendi Cocoa Touch uygulaması ve temel API'leri ile birlikte proje, iOS Uygulama kodunun UWP uygulamaları içinde yeniden kullanılmasına olanak tanır.

Windows'ta Objective-C Geliştirme araçları GNUStep'in web sitesinden indirilebilir. GNUStep Geliştirme Sistemi aşağıdaki paketlerden oluşmaktadır: GNUstep MSYS System, GNUstep Core, GNUstep Devel, GNUstep Cairo, ProjectCenter IDE (Xcode gibi, ancak karmaşık değil), Gorm (Xcode NIB oluşturucu gibi Arayüz Oluşturucu). Bu ikili yükleyiciler 2016'dan beri güncellenmemiştir, bu nedenle bunun yerine Cygwin veya MSYS2 altında oluşturarak yüklemek daha iyi bir fikir olabilir.

Kütüphane kullanımı

Objective-C günümüzde genellikle Cocoa, GNUstep veya ObjFW gibi standart nesnelerden oluşan sabit bir kütüphane (genellikle "kit" veya "çerçeve" olarak bilinir) ile birlikte kullanılır. Bu kütüphaneler genellikle işletim sistemiyle birlikte gelir: GNUstep kütüphaneleri genellikle Linux tabanlı dağıtımlarla, Cocoa ise macOS ile birlikte gelir. Programcı, mevcut temel sınıftan (NSObject / OFObject) işlevsellik devralmak zorunda değildir. Objective-C, mevcut herhangi bir işlevselliği miras almayan yeni kök sınıfların bildirimine izin verir. Başlangıçta, Objective-C tabanlı programlama ortamları tipik olarak neredeyse tüm diğer sınıfların miras aldığı temel sınıf olarak bir Object sınıfı sunuyordu. OpenStep'in tanıtılmasıyla NeXT, Object'e ek özellikler sunan (örneğin ham işaretçiler yerine nesne referansları ve referans sayımı kullanmaya vurgu yapan) NSObject adında yeni bir temel sınıf oluşturdu. Cocoa'daki neredeyse tüm sınıflar NSObject'ten miras alınmıştır.

Yeniden adlandırma yalnızca OpenStep API'sindeki sınıfların yeni varsayılan davranışını farklılaştırmakla kalmadı, aynı zamanda NeXTSTEP'te (ve aşağı yukarı diğer Objective-C sınıf kütüphanelerinde) kullanılan orijinal temel sınıf olan Object'i kullanan kodun NSObject'i kullanan kodla (bazı sınırlamalarla) aynı çalışma zamanında birlikte var olmasına izin verdi. İki harfli ön ekin getirilmesi aynı zamanda Objective-C'de bulunmayan isim alanlarının basit bir biçimi haline geldi. Gayri resmi bir paketleme tanımlayıcısı oluşturmak için bir önek kullanmak Objective-C topluluğunda gayri resmi bir kodlama standardı haline geldi ve bugüne kadar devam ediyor.

Son zamanlarda, hem bir paket yöneticisi hem de bir paket deposu olmayı amaçlayan CocoaPods gibi paket yöneticileri ortaya çıkmaya başladı. Son birkaç yılda yazılan pek çok açık kaynak Objective-C kodu artık CocoaPods kullanılarak yüklenebilmektedir.

Dilin analizi

Objective-C uygulamaları, C dilinde yazılmış ince bir çalışma zamanı sistemi kullanır ve bu da uygulamanın boyutuna çok az katkıda bulunur. Bunun aksine, yaratıldığı dönemde çoğu nesne yönelimli sistem büyük sanal makine çalışma zamanları kullanıyordu. Objective-C'de yazılan programlar, sadece bir pencere açmak için büyük miktarda bellek kullanılan Smalltalk sistemlerinin aksine, kodlarının ve kütüphanelerin (genellikle yazılım dağıtımına dahil edilmesi gerekmeyen) boyutundan çok daha büyük olmama eğilimindedir. Objective-C uygulamaları benzer C veya C++ uygulamalarından daha büyük olma eğilimindedir, çünkü Objective-C dinamik yazım metotların soyulmasına veya inline edilmesine izin vermez. Programcı temsilci atama, çağrıları iletme, anında seçiciler oluşturma ve bunları çalışma zamanı sistemine aktarma özgürlüğüne sahip olduğundan, Objective-C derleyicisi kullanılmayan yöntemleri kaldırmanın veya çağrıları satır içi yapmanın güvenli olduğunu varsayamaz.

Aynı şekilde, dil yeni bir derleyici yerine mevcut C derleyicileri üzerinde (GCC'de önce bir önişlemci, sonra bir modül olarak) uygulanabilir. Bu, Objective-C'nin mevcut büyük C kodu, kütüphaneleri, araçları vb. koleksiyonundan yararlanmasını sağlar. Mevcut C kütüphaneleri, OO tarzı bir arayüz sağlamak için Objective-C sarmalayıcılarına sarılabilir. Bu yönüyle GTK uygulamalarının geliştirilmesinde yaygın olarak kullanılan GObject kütüphanesi ve Vala diline benzemektedir.

Tüm bu pratik değişiklikler, 1980'lerde Smalltalk'ın yaygın olarak kabul görmesinin önündeki en büyük sorun olan giriş engelini azaltmıştır.

Yaygın bir eleştiri Objective-C'nin isim alanları için dil desteğine sahip olmamasıdır. Bunun yerine, programcılar geleneksel olarak ad alanı adlarından daha kısa olan ve bu nedenle çarpışmalara daha yatkın olan sınıf adlarına ön ekler eklemek zorunda kalmaktadır. 2007'den itibaren, Cocoa programlama ortamındaki tüm macOS sınıfları ve işlevleri, macOS veya iOS çekirdeğine ait olduklarını belirtmek için "NS" (örn. NSObject, NSButton) ile ön ek alır; "NS", NeXTSTEP'in geliştirilmesi sırasında tanımlanan sınıfların adlarından türetilmiştir.

Objective-C, C'nin katı bir üst kümesi olduğundan, C ilkel türlerine birinci sınıf nesneler olarak davranmaz.

C++'ın aksine, Objective-C operatör aşırı yüklemesini desteklemez. Ayrıca C++'dan farklı olarak Objective-C, bir nesnenin yalnızca bir sınıftan doğrudan kalıtım almasına izin verir (çoklu kalıtımı yasaklar). Bununla birlikte, çoğu durumda, kategoriler ve protokoller aynı sonuçları elde etmek için alternatif yollar olarak kullanılabilir.

Objective-C dinamik çalışma zamanı yazımı kullandığından ve tüm yöntem çağrıları işlev çağrıları (veya bazı durumlarda sistem çağrıları) olduğundan, birçok yaygın performans optimizasyonu Objective-C yöntemlerine uygulanamaz (örneğin: inlining, sabit yayılım, prosedürler arası optimizasyonlar ve toplamların skaler değişimi). Bu, Objective-C soyutlamalarının performansını, bu tür optimizasyonların mümkün olduğu C++ gibi dillerdeki benzer soyutlamalara göre sınırlar.

Bellek yönetimi

Objective-C'nin ilk sürümleri çöp toplamayı desteklemiyordu. O zamanlar bu karar bazı tartışmalara neden olmuş ve birçok kişi uzun "ölü zamanların" (Smalltalk'un toplama yaptığı zamanlar) tüm sistemi kullanılamaz hale getirdiğini düşünmüştür. Bazı 3. parti uygulamalar bu özelliği ekledi (en önemlisi Boehm kullanan GNUstep) ve Apple Mac OS X v10.5'ten itibaren bunu uyguladı. Bununla birlikte, macOS ve iOS'un daha yeni sürümlerinde, çöp toplama, 2011 yılında tanıtılan Otomatik Referans Sayma (ARC) lehine kullanımdan kaldırılmıştır.

ARC ile derleyici, statik kod analizine dayalı olarak tutma ve bırakma çağrılarını Objective-C koduna otomatik olarak ekler. Bu otomasyon, programcıyı bellek yönetimi kodu yazma zorunluluğundan kurtarır. ARC ayrıca Objective-C diline zayıf referanslar da ekler.

Objective-C ve C++ arasındaki felsefi farklar

C++ ve Objective-C'nin tasarım ve uygulamaları, C'yi genişletmeye yönelik temelde farklı yaklaşımları temsil etmektedir.

C'nin prosedürel programlama tarzına ek olarak, C++ nesne yönelimli programlama, genel programlama ve metaprogramlamanın belirli biçimlerini doğrudan destekler. C++ ayrıca çeşitli konteyner sınıfları içeren geniş bir standart kütüphaneye sahiptir. Benzer şekilde Objective-C, C++'a nesne yönelimli programlama, dinamik yazma ve yansıtma özelliklerini ekler. Objective-C kendi başına standart bir kütüphane sağlamaz, ancak Objective-C'nin kullanıldığı çoğu yerde, C++'ın standart kütüphanesine benzer işlevler sağlayan OPENSTEP, Cocoa veya GNUstep gibi OpenStep benzeri bir kütüphane ile birlikte kullanılır.

Dikkate değer bir fark, Objective-C'nin yansıtıcı özellikler için çalışma zamanı desteği sağlamasıdır, oysa C++, C'ye yalnızca küçük bir miktar çalışma zamanı desteği ekler. Objective-C'de, bir nesne kendi özellikleri hakkında sorgulanabilir, örneğin, belirli bir mesaja yanıt verip vermeyeceği. C++'da bu, harici kütüphaneler kullanılmadan mümkün değildir.

Yansımanın kullanımı, bir dilin dinamik (çalışma zamanı) özellikleri ile statik (derleme zamanı) özellikleri arasındaki daha geniş ayrımın bir parçasıdır. Objective-C ve C++ her iki özelliğin bir karışımını kullansa da, Objective-C kesinlikle çalışma zamanı kararlarına yönelikken, C++ derleme zamanı kararlarına yöneliktir. Dinamik ve statik programlama arasındaki gerilim, programlamadaki klasik değiş tokuşların çoğunu içerir: dinamik özellikler esneklik katarken, statik özellikler hız ve tip denetimi katar.

Genel programlama ve metaprogramlama, çalışma zamanı çok biçimliliği kullanılarak her iki dilde de uygulanabilir. C++'da bu sanal fonksiyonlar ve çalışma zamanı tip tanımlama şeklindeyken, Objective-C dinamik tipleme ve yansıma sunar. Hem Objective-C hem de C++ derleme zamanı çok biçimliliğini (jenerik fonksiyonlar) desteklerken, Objective-C bu özelliği yalnızca 2015 yılında eklemiştir.