Objective-C

**Objective-C** adalah bahasa pemrograman tingkat tinggi untuk tujuan umum dan berorientasi objek yang menambahkan fitur pengiriman pesan (*messaging*) gaya Smalltalk ke dalam bahasa pemrograman C. Awalnya dikembangkan oleh Brad Cox dan Tom Love pada awal 1980-an, bahasa ini dipilih oleh NeXT untuk sistem operasi NeXTSTEP mereka. Karena garis keturunan langsung dari sistem operasi Apple macOS berasal dari NeXTSTEP, Objective-C menjadi bahasa standar yang digunakan, didukung, dan dipromosikan oleh Apple untuk mengembangkan aplikasi macOS dan iOS (melalui antarmuka pemrograman aplikasi (API) masing-masing, Cocoa dan Cocoa Touch) dari tahun 1997, ketika Apple membeli NeXT, hingga pengenalan bahasa Swift pada tahun 2014.

Program Objective-C yang dikembangkan untuk sistem operasi non-Apple atau yang tidak bergantung pada API Apple juga dapat dikompilasi untuk platform komputer apa pun yang didukung oleh GNU Compiler Collection (GCC) atau LLVM/Clang.

Berkas program 'messaging/implementation' kode sumber Objective-C biasanya memiliki ekstensi nama berkas , sedangkan berkas 'header/interface' Objective-C memiliki ekstensi , sama seperti berkas header C. Berkas Objective-C++ ditandai dengan ekstensi nama berkas .

## Sejarah
Objective-C diciptakan terutama oleh Brad Cox dan Tom Love pada awal 1980-an di perusahaan mereka, Productivity Products International (PPI).

Menjelang pendirian perusahaan mereka, keduanya telah diperkenalkan dengan Smalltalk saat bekerja di Pusat Teknologi Pemrograman ITT Corporation pada tahun 1981. Karya paling awal pada Objective-C bermula sekitar waktu tersebut. Cox tertarik pada masalah kegunaan ulang (*reusability*) sejati dalam desain perangkat lunak dan pemrograman. Ia menyadari bahwa bahasa seperti Smalltalk akan sangat berharga dalam membangun lingkungan pengembangan bagi pengembang sistem di ITT. Namun, ia dan Tom Love juga mengakui bahwa kompatibilitas mundur dengan C sangatlah penting dalam lingkungan rekayasa telekomunikasi ITT.

Cox mulai menulis sebuah pra-prosesor untuk C guna menambahkan beberapa kemampuan Smalltalk. Tak lama kemudian, ia memiliki implementasi kerja dari ekstensi berorientasi objek untuk bahasa C, yang ia beri nama Object-Oriented Pre-Compiler (OOPC).

Love dipekerjakan oleh Riset Schlumberger pada tahun 1982 dan berkesempatan mendapatkan salinan komersial pertama Smalltalk-80, yang semakin memengaruhi pengembangan gagasan mereka. Untuk menunjukkan bahwa kemajuan nyata dapat dicapai, Cox menunjukkan bahwa pembuatan komponen perangkat lunak yang dapat dipertukarkan sebenarnya hanya membutuhkan sedikit perubahan praktis pada alat yang ada. Secara khusus, mereka perlu mendukung objek secara fleksibel, dilengkapi dengan set pustaka yang dapat digunakan, dan memungkinkan kode (serta sumber daya apa pun yang dibutuhkan oleh kode tersebut) untuk dibundel menjadi satu format lintas platform.

Love dan Cox akhirnya membentuk PPI untuk mengomersialkan produk mereka, yang menggabungkan kompiler Objective-C dengan pustaka kelas. Pada tahun 1986, Cox menerbitkan deskripsi utama Objective-C dalam bentuk aslinya dalam buku *Object-Oriented Programming, An Evolutionary Approach*. Meskipun ia berhati-hati dalam menjelaskan bahwa masalah kegunaan ulang tidak hanya sekadar apa yang disediakan oleh Objective-C, bahasa tersebut sering kali dibandingkan fitur demi fitur dengan bahasa lainnya.

### Popularisasi melalui NeXT
Pada tahun 1988, NeXT melisensikan Objective-C dari StepStone (nama baru PPI, pemilik merek dagang Objective-C) dan memperluas kompiler GCC untuk mendukung Objective-C. NeXT mengembangkan pustaka Application Kit (AppKit) dan Foundation Kit yang menjadi basis bagi antarmuka pengguna NeXTSTEP dan Interface Builder. Meskipun stasiun kerja (*workstation*) NeXT gagal memberikan dampak besar di pasar, peralatan pengembangannya dipuji secara luas di industri tersebut. NeXT kemudian menghentikan produksi perangkat keras dan fokus pada peralatan perangkat lunak, dengan menjual NeXTSTEP (dan OPENSTEP) sebagai platform untuk pemrograman khusus.

Untuk mengakali ketentuan GPL, NeXT awalnya berniat mengirimkan *frontend* Objective-C secara terpisah, yang memungkinkan pengguna untuk menghubungkannya dengan GCC guna menghasilkan eksekusi kompiler. Meskipun awalnya diterima oleh Richard M. Stallman, rencana ini ditolak setelah Stallman berkonsultasi dengan pengacara GNU, dan NeXT setuju untuk menjadikan Objective-C sebagai bagian dari GCC.

Upaya untuk memperluas GNU Compiler Collection (GCC) dipimpin oleh Steve Naroff, yang bergabung ke NeXT dari StepStone. Perubahan kompiler tersebut tersedia sesuai dengan ketentuan Lisensi Publik Umum GNU (GPL), tetapi pustaka runtime-nya tidak, sehingga kontribusi sumber terbuka tersebut tidak dapat digunakan oleh masyarakat umum. Hal ini menyebabkan pihak lain mengembangkan pustaka runtime serupa di bawah lisensi sumber terbuka. Di kemudian hari, Steve Naroff juga merupakan kontributor utama dalam upaya Apple membangun *frontend* Objective-C untuk Clang.

Proyek GNU mulai mengerjakan implementasi perangkat lunak bebas untuk Cocoa, yang diberi nama GNUstep, berdasarkan standar OpenStep. Dennis Glatting menulis runtime GNU Objective-C pertama pada tahun 1992. Runtime GNU Objective-C yang digunakan saat ini (sejak 1993) adalah yang dikembangkan oleh Kresten Krab Thorup saat ia masih menjadi mahasiswa universitas di Denmark. Thorup juga bekerja di NeXT dari tahun 1993 hingga 1996.

### Pengembangan Apple dan Swift
Setelah mengakuisisi NeXT pada tahun 1996, Apple Computer menggunakan OpenStep dalam sistem operasi barunya saat itu, Mac OS X. Ini mencakup Objective-C, alat pengembang berbasis Objective-C milik NeXT yaitu Project Builder, serta alat desain antarmukanya, Interface Builder. Keduanya kemudian digabungkan menjadi satu aplikasi, Xcode. Sebagian besar Cocoa API Apple saat ini didasarkan pada objek antarmuka OpenStep dan merupakan lingkungan Objective-C paling signifikan yang digunakan untuk pengembangan aktif.

Pada WWDC 2014, Apple memperkenalkan bahasa baru, Swift, yang dideskripsikan sebagai "Objective-C tanpa C".

## Sintaksis
Objective-C merupakan lapisan tipis di atas C dan merupakan "superset ketat" dari C. Ini berarti dimungkinkan untuk mengompilasi program C apa pun dengan kompiler Objective-C dan menyertakan kode bahasa C secara bebas di dalam kelas Objective-C.

Objective-C menurunkan sintaksis objeknya dari Smalltalk. Semua sintaksis untuk operasi non-orientasi objek (termasuk variabel primitif, pra-pemrosesan, ekspresi, deklarasi fungsi, dan pemanggilan fungsi) identik dengan yang ada pada C, sedangkan sintaksis untuk fitur berorientasi objek adalah implementasi dari pengiriman pesan (*messaging*) gaya Smalltalk.

### Pesan
Model pemrograman berorientasi objek dalam Objective-C didasarkan pada pengiriman pesan ke instansi objek. Dalam Objective-C, seseorang tidak *memanggil metode*; melainkan *mengirim pesan*. Hal ini berbeda dengan model pemrograman gaya Simula yang digunakan oleh C++. Perbedaan antara kedua konsep ini terletak pada bagaimana kode yang dirujuk oleh nama metode atau pesan dieksekusi. Dalam bahasa gaya Simula, nama metode—dalam banyak kasus—diikat (*bound*) ke bagian kode di kelas target oleh kompiler. Dalam Smalltalk dan Objective-C, target pesan diselesaikan pada saat runtime (saat program berjalan), di mana objek penerima itu sendiri yang menginterpretasikan pesan tersebut.

Sebuah metode diidentifikasi oleh sebuah *selector* atau  — pengenal unik untuk setiap nama pesan, seringkali berupa -terminated string yang mewakili namanya—dan diselesaikan menjadi sebuah pointer metode C yang mengimplementasikannya: sebuah . Konsekuensi dari hal ini adalah sistem pengiriman pesan tidak memiliki pengecekan tipe. Objek yang dituju oleh pesan tersebut—sang *receiver* (penerima)—tidak dijamin untuk merespons pesan, dan jika tidak merespons, ia akan memicu pengecualian (*exception*).

Mengirim pesan  ke objek yang ditunjuk oleh pointer  akan memerlukan kode berikut dalam C++:


```cpp
obj->method(argument);
```


Dalam Objective-C, hal ini ditulis sebagai berikut:


```objc
[obj method:argument];
```


Pemanggilan "method" tersebut diterjemahkan oleh kompiler ke keluarga fungsi runtime . Implementasi yang berbeda menangani tambahan modern seperti . Dalam keluarga GNU, fungsi ini dinamakan , namun telah ditinggalkan demi sistem pencarian modern di bawah .

Kedua gaya pemrograman ini memiliki berbagai kelebihan dan kekurangan. Pemrograman berorientasi objek dalam gaya Simula (C++) memungkinkan pewarisan jamak (*multiple inheritance*) dan eksekusi yang lebih cepat dengan menggunakan pengikatan waktu kompilasi (*compile-time binding*) jika memungkinkan, tetapi tidak mendukung pengikatan dinamis secara default. Gaya ini juga memaksa semua metode memiliki implementasi yang sesuai kecuali jika metode tersebut bersifat abstrak. Pemrograman gaya Smalltalk seperti yang digunakan dalam Objective-C memungkinkan pesan tidak terimplementasi, dengan metode yang diselesaikan ke implementasinya pada saat runtime. Sebagai contoh, sebuah pesan dapat dikirim ke sekumpulan objek, di mana hanya beberapa objek yang diharapkan untuk merespons, tanpa takut menghasilkan kesalahan runtime. Pengiriman pesan juga tidak mengharuskan suatu objek ditentukan pada saat waktu kompilasi. (Lihat bagian pengetikan dinamis di bawah untuk keuntungan lebih lanjut dari pengikatan dinamis/akhir.)

## Antarmuka dan Implementasi
Objective-C mengharuskan antarmuka (*interface*) dan implementasi dari sebuah kelas berada dalam blok kode yang dideklarasikan secara terpisah. Berdasarkan konvensi, pengembang menempatkan antarmuka dalam sebuah berkas header dan implementasi dalam berkas kode. Berkas header, yang biasanya berakhiran .h, mirip dengan berkas header C, sedangkan berkas implementasi (metode), yang biasanya berakhiran .m, bisa sangat mirip dengan berkas kode C.
#### Antarmuka
Ini serupa dengan deklarasi kelas yang digunakan dalam bahasa berorientasi objek lainnya, seperti C++ atau Python.

Antarmuka sebuah kelas biasanya didefinisikan dalam berkas header. Konvensi umum yang digunakan adalah menamai berkas header sesuai dengan nama kelasnya, misalnya  akan berisi antarmuka untuk kelas .

Deklarasi antarmuka mengambil bentuk sebagai berikut:

```objc
@interface NamaKelas : NamaKelasInduk {
  // variabel instansi
}
+ metodeKelas1;
+ (tipe_kembalian)metodeKelas2;
+ (tipe_kembalian)metodeKelas3:(tipe_param1)nama_var_param1;

- (tipe_kembalian)metodeInstansi1Dengan1Parameter:(tipe_param1)nama_var_param1;
- (tipe_kembalian)metodeInstansi2Dengan2Parameter:(tipe_param1)nama_var_param1
                                  namaPanggilParam2:(tipe_param2)nama_var_param2;
@end
```


Pada contoh di atas, tanda plus (+) menunjukkan metode kelas, yaitu metode yang dapat dipanggil pada kelas itu sendiri (bukan pada instansi), dan tanda minus (-) menunjukkan metode instansi, yang hanya dapat dipanggil pada instansi tertentu dari kelas tersebut. Metode kelas juga tidak memiliki akses ke variabel instansi.

Kode di atas secara kasar setara dengan antarmuka C++ berikut:


```cpp
class NamaKelas : public NamaKelasInduk {
protected:
  // variabel instansi

public:
  // Fungsi kelas (statis)
  static void *metodeKelas1();
  static tipe_kembalian metodeKelas2();
  static tipe_kembalian metodeKelas3(tipe_param1 nama_var_param1);

  // Fungsi instansi (anggota)
  tipe_kembalian metodeInstansi1Dengan1Parameter(tipe_param1 nama_var_param1);
  tipe_kembalian
  metodeInstansi2Dengan2Parameter(tipe_param1 nama_var_param1,
                                  tipe_param2 nama_var_param2 = default);
};
```


Perhatikan bahwa  menunjukkan penyisipan segmen selektor dengan ekspresi argumen, di mana tidak ada padanan langsungnya dalam C/C++.

Tipe kembalian dapat berupa tipe C standar apa pun, pointer ke objek Objective-C generik, pointer ke tipe objek tertentu seperti NSArray *, NSImage *, atau NSString *, atau pointer ke kelas tempat metode tersebut berada (instancetype). Tipe kembalian default adalah tipe Objective-C generik .

Argumen metode dimulai dengan nama label yang menjadi bagian dari nama metode, diikuti oleh titik dua, kemudian tipe argumen yang diharapkan dalam tanda kurung, dan nama argumen tersebut. Label dapat diabaikan.


```objc
- (void)setRangeStart:(int)start end:(int)end;
- (void)importDocumentWithName:(NSString *)name
      withSpecifiedPreferences:(Preferences *)prefs
                    beforePage:(int)insertPage;
```


Turunan dari definisi antarmuka adalah *category* (kategori), yang memungkinkan seseorang untuk menambahkan metode ke kelas yang sudah ada tanpa perlu mengubah kode aslinya.

#### Implementasi
Antarmuka hanya mendeklarasikan tampilan luar kelas dan bukan metode itu sendiri: kode aktual ditulis dalam berkas implementasi. Berkas implementasi (metode) biasanya memiliki ekstensi berkas `.m`, yang awalnya berarti "messages" (pesan).


```objc
@implementation namakelas
+ (tipe_kembalian)metodeKelas {
  // implementasi
}
- (tipe_kembalian)metodeInstansi {
  // implementasi
}
@end
```


Metode ditulis menggunakan deklarasi antarmukanya.
Perbandingan antara Objective-C dan C:


```objc
- (int)method:(int)i {
  return [self square_root:i];
}
```



```c
int function(int i) {
  return square_root(i);
}
```


Sintaksis ini memungkinkan pemberian nama semu pada argumen.


```objc
- (void)ubahWarnaKeMerah:(float)red hijau:(float)green biru:(float)blue {
  //... Implementasi ...
}

// Dipanggil seperti ini:
[warnaSaya ubahWarnaKeMerah:5.0 hijau:2.0 biru:6.0];
```


Representasi internal dari sebuah metode bervariasi di antara implementasi Objective-C yang berbeda. Jika warnaSaya berasal dari kelas , metode instansi  mungkin secara internal dilabeli . Huruf  merujuk pada metode instansi, diikuti nama kelas dan nama metode, dengan titik dua diubah menjadi garis bawah. Karena urutan parameter adalah bagian dari nama metode, urutan tersebut tidak dapat diubah hanya untuk menyesuaikan gaya penulisan, berbeda dengan parameter bernama yang sebenarnya.

Namun, nama internal fungsi jarang digunakan secara langsung. Secara umum, pesan dikonversi menjadi pemanggilan fungsi yang didefinisikan dalam pustaka runtime Objective-C. Tidak selalu diketahui pada saat penautan (*link time*) metode mana yang akan dipanggil karena kelas dari penerima pesan tidak perlu diketahui hingga saat runtime.

#### Instansiasi
Setelah kelas Objective-C ditulis, kelas tersebut dapat diinstansiasi. Hal ini dilakukan dengan mengalokasikan instansi kelas yang belum diinisialisasi (sebuah objek) terlebih dahulu, kemudian menginisialisasinya. Sebuah objek tidak berfungsi penuh sampai kedua langkah tersebut selesai dilakukan. Langkah-langkah ini sebaiknya diselesaikan dalam satu baris kode agar tidak ada objek teralokasi yang belum melalui inisialisasi (dan karena tidak bijaksana menyimpan hasil perantara karena metode `-init` dapat mengembalikan objek yang berbeda dari objek tempat ia dipanggil).

Instansiasi dengan penginisialisasi default tanpa parameter:


```objc
MyObject *foo = [[MyObject alloc] init];
```


Instansiasi dengan penginisialisasi khusus:


```objc
MyObject *foo = [[MyObject alloc] initWithString:myString];
```


Dalam kasus di mana tidak ada inisialisasi khusus yang dilakukan, metode "new" sering kali dapat digunakan sebagai pengganti pesan alloc-init:


```objc
MyObject *foo = [MyObject new];
```


Selain itu, beberapa kelas mengimplementasikan penginisialisasi metode kelas. Seperti `+new`, metode ini menggabungkan `+alloc` dan `-init`, tetapi berbeda dengan `+new`, metode tersebut mengembalikan instansi yang sudah masuk ke *autorelease pool*. Beberapa penginisialisasi metode kelas menerima parameter:


```objc
MyObject *foo = [MyObject object];
MyObject *bar = [MyObject objectWithString:@"Wikipedia :)"];
```


Pesan *alloc* mengalokasikan memori yang cukup untuk menampung semua variabel instansi bagi sebuah objek, menyetel semua variabel instansi ke nilai nol, dan mengubah memori tersebut menjadi instansi dari kelas tersebut; pada titik mana pun selama inisialisasi, memori tersebut bukanlah instansi dari kelas induknya (superclass).

Pesan *init* melakukan pengaturan instansi saat pembuatan. Metode *init* sering kali ditulis sebagai berikut:


```objc
- (id)init {
    self = [super init];
    if (self) {
        // lakukan inisialisasi objek di sini
    }
    return self;
}
```


Pada contoh di atas, perhatikan tipe kembalian . Tipe ini berarti *pointer ke objek apa pun* dalam Objective-C (Lihat bagian Pengetikan dinamis).

Pola penginisialisasi digunakan untuk memastikan bahwa objek diinisialisasi dengan benar oleh kelas induknya sebelum metode init melakukan inisialisasinya sendiri. Pola ini melakukan tindakan berikut:

* Baris 2
*: Mengirim pesan  ke instansi kelas induk dan memberikan hasilnya ke  (pointer ke objek saat ini).
* Baris 3
*: Memeriksa apakah pointer objek yang dikembalikan valid sebelum melakukan inisialisasi apa pun.
* Baris 6
*: Mengembalikan nilai self ke pemanggil.

Pointer objek yang tidak valid memiliki nilai ; pernyataan kondisional seperti  memperlakukan nil seperti pointer null, sehingga kode inisialisasi tidak akan dieksekusi jika  mengembalikan nil. Jika terjadi kesalahan dalam inisialisasi, metode init harus melakukan pembersihan yang diperlukan, termasuk mengirim pesan  ke self, dan mengembalikan  untuk menunjukkan bahwa inisialisasi gagal. Pemeriksaan kesalahan semacam itu hanya boleh dilakukan setelah memanggil inisialisasi kelas induk untuk memastikan bahwa penghancuran objek dilakukan dengan benar.

Jika sebuah kelas memiliki lebih dari satu metode inisialisasi, hanya satu dari mereka (*designated initializer* atau penginisialisasi utama) yang perlu mengikuti pola ini; metode lainnya harus memanggil penginisialisasi utama alih-alih penginisialisasi kelas induk.

### Protokol
Dalam bahasa pemrograman lain, ini disebut sebagai *interface* (antarmuka).

Objective-C diperluas di NeXT untuk memperkenalkan konsep pewarisan jamak spesifikasi (namun bukan implementasi) melalui pengenalan protokol. Ini adalah pola yang bisa dicapai baik sebagai kelas dasar abstrak dengan pewarisan jamak di C++, atau sebagai *interface* (seperti dalam Java dan C#). Objective-C menggunakan protokol ad hoc yang disebut *protokol informal* dan protokol yang dipaksakan oleh kompiler yang disebut *protokol formal*.

Protokol informal adalah daftar metode yang dapat dipilih oleh sebuah kelas untuk diimplementasikan. Hal ini ditentukan dalam dokumentasi, karena tidak memiliki kehadiran fisik dalam bahasa. Protokol informal diimplementasikan sebagai sebuah kategori (lihat di bawah) pada NSObject dan sering kali menyertakan metode opsional, yang jika diimplementasikan, dapat mengubah perilaku sebuah kelas. Misalnya, sebuah kelas kolom teks mungkin memiliki delegasi yang mengimplementasikan protokol informal dengan metode opsional untuk melakukan pengisian otomatis (*auto-completion*) dari teks yang diketik pengguna. Kolom teks tersebut mencari tahu apakah delegasi mengimplementasikan metode itu (melalui pemrograman reflektif (refleksi)) dan, jika ya, memanggil metode delegasi tersebut untuk mendukung fitur pengisian otomatis.

Protokol formal mirip dengan *interface* dalam Java, C#, dan Ada 2005. Ini adalah daftar metode yang dapat dideklarasikan oleh kelas mana pun untuk diimplementasikan. Versi Objective-C sebelum 2.0 mengharuskan sebuah kelas untuk mengimplementasikan semua metode dalam protokol yang dideklarasikannya; kompiler akan mengeluarkan kesalahan jika kelas tersebut tidak mengimplementasikan setiap metode dari protokol yang dideklarasikan. Objective-C 2.0 menambahkan dukungan untuk menandai metode tertentu dalam protokol sebagai opsional, dan kompiler tidak akan memaksakan implementasi metode opsional tersebut.

Sebuah kelas harus dideklarasikan mengimplementasikan protokol tersebut untuk dikatakan mematuhinya (*conform*). Hal ini dapat dideteksi pada saat runtime. Protokol formal tidak dapat menyediakan implementasi apa pun; mereka hanya menjamin pemanggil bahwa kelas-kelas yang mematuhi protokol tersebut akan menyediakan implementasi. Dalam pustaka NeXT/Apple, protokol sering digunakan oleh sistem Distributed Objects untuk mewakili kemampuan sebuah objek yang dieksekusi pada sistem jarak jauh.

Sintaksis:


```objc
@protocol NSLocking
- (void)lock;
- (void)unlock;
@end
```


menunjukkan bahwa terdapat ide abstrak tentang penguncian (*locking*). Dengan menyatakan dalam definisi kelas bahwa protokol tersebut diimplementasikan:


```objc
@interface NSLock : NSObject <NSLocking>
// ...
@end
```


instansi dari NSLock menyatakan bahwa mereka akan menyediakan implementasi untuk kedua metode instansi tersebut.

### Pengetikan dinamis
Objective-C, seperti halnya Smalltalk, dapat menggunakan pengetikan dinamis: sebuah objek dapat dikirimi pesan yang tidak ditentukan dalam antarmukanya. Hal ini memungkinkan fleksibilitas yang lebih besar, karena memungkinkan sebuah objek untuk "menangkap" sebuah pesan dan mengirimkan pesan tersebut ke objek lain yang dapat merespons pesan tersebut dengan tepat, atau sebaliknya meneruskan pesan tersebut ke objek lainnya lagi. Perilaku ini dikenal sebagai *message forwarding* (penerusan pesan) atau *delegation* (delegasi). Sebagai alternatif, penangan kesalahan (*error handler*) dapat digunakan jika pesan tidak dapat diteruskan. Jika sebuah objek tidak meneruskan pesan, meresponsnya, atau menangani kesalahan, maka sistem akan menghasilkan pengecualian runtime (*runtime exception*). Jika pesan dikirim ke *nil* (pointer objek null), pesan tersebut akan diabaikan secara diam-diam atau memicu pengecualian generik, tergantung pada opsi kompiler.

Informasi pengetikan statis juga dapat ditambahkan secara opsional ke variabel. Informasi ini kemudian diperiksa pada saat waktu kompilasi (*compile time*). Dalam empat pernyataan berikut, informasi tipe yang disediakan semakin spesifik. Pernyataan-pernyataan tersebut setara pada saat runtime, tetapi informasi tambahan memungkinkan kompiler untuk memperingatkan pemrogram jika argumen yang dimasukkan tidak sesuai dengan tipe yang ditentukan.


```objc
- (void)setMyValue:(id)foo;
```

Dalam pernyataan di atas, *foo* dapat berupa kelas apa pun.


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

Dalam pernyataan di atas, *foo* dapat berupa instansi dari kelas apa pun yang mematuhi protokol *<code>NSCopying</code>*.


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

Dalam pernyataan di atas, *foo* harus merupakan instansi dari kelas *NSNumber*.


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

Dalam pernyataan di atas, *foo* harus merupakan instansi dari kelas *NSNumber*, dan harus mematuhi protokol *<code>NSCopying</code>*.

Dalam Objective-C, semua objek direpresentasikan sebagai pointer, dan inisialisasi statis tidak diperbolehkan. Objek yang paling sederhana adalah tipe yang ditunjuk oleh  (), yang hanya memiliki pointer *isa* yang mendeskripsikan kelasnya. Tipe lain dari C, seperti nilai dan struct, tidak berubah karena mereka bukan bagian dari sistem objek. Keputusan ini berbeda dengan model objek C++, di mana struct dan kelas disatukan.

### Penerusan
Objective-C mengizinkan pengiriman pesan ke objek yang mungkin tidak merespons. Alih-alih merespons atau mengabaikan pesan begitu saja, sebuah objek dapat meneruskan pesan ke objek lain yang dapat merespons. Penerusan (*forwarding*) dapat digunakan untuk menyederhanakan implementasi pola desain tertentu, seperti pola observer atau pola proxy.

Runtime Objective-C menentukan sepasang metode dalam 
* metode penerusan:
```objc
- (retval_t)forward:(SEL)sel args:(arglist_t)args; // dengan GCC
- (id)forward:(SEL)sel args:(marg_list)args; // dengan sistem NeXT/Apple
```

* metode aksi:
```objc
- (retval_t)performv:(SEL)sel args:(arglist_t)args; // dengan GCC
- (id)performv:(SEL)sel args:(marg_list)args; // dengan sistem NeXT/Apple
```


Objek yang ingin mengimplementasikan penerusan hanya perlu menimpa (*override*) metode penerusan dengan metode baru untuk menentukan perilaku penerusan tersebut. Metode aksi  tidak perlu ditimpa, karena metode ini hanya melakukan aksi berdasarkan selektor dan argumen. Perhatikan tipe `SEL`, yang merupakan tipe pesan dalam Objective-C.

Catatan: dalam OpenStep, Cocoa, dan GNUstep (kerangka kerja Objective-C yang umum digunakan), seseorang tidak menggunakan kelas . Metode  dari kelas  digunakan untuk melakukan penerusan.

#### Contoh
Berikut adalah contoh program yang mendemonstrasikan dasar-dasar penerusan (*forwarding*).

; *Forwarder.h*

```objc
#import <objc/Object.h>

@interface Forwarder : Object {
  id recipient; // Objek yang ingin kita tuju untuk meneruskan pesan.
}

// Metode akses (accessor).
- (id)recipient;
- (id)setRecipient:(id)_recipient;
@end
```


; *Forwarder.m*

```objc
#import "Forwarder.h"

@implementation Forwarder
- (retval_t)forward:(SEL)sel args:(arglist_t)args {
  /*
  * Periksa apakah penerima benar-benar merespons pesan tersebut.
  * Hal ini mungkin diinginkan atau tidak, misalnya, jika penerima
  * pada gilirannya tidak merespons pesan tersebut, ia mungkin melakukan
  * penerusan sendiri.
  */
  if ([recipient respondsToSelector:sel]) {
    return [recipient performv:sel args:args];
  } else {
    return [self error:"Penerima tidak merespons"];
  }
}

- (id)setRecipient:(id)_recipient {
  [recipient autorelease];
  recipient = [_recipient retain];
  return self;
}

- (id)recipient {
  return recipient;
}
@end
```


; *Recipient.h*

```objc
#import <objc/Object.h>

// Objek Penerima sederhana.
@interface Recipient : Object
- (id)hello;
@end
```


; *Recipient.m*

```objc
#import "Recipient.h"

@implementation Recipient

- (id)hello {
  printf("Penerima mengatakan halo!\n");

  return self;
}

@end
```


; *main.m*

```objc
#import "Forwarder.h"
#import "Recipient.h"

int main(void) {
  Forwarder *forwarder = [Forwarder new];
  Recipient *recipient = [Recipient new];

  [forwarder setRecipient:recipient]; // Atur penerima.
  /*
  * Perhatikan bahwa forwarder tidak merespons pesan hello! Pesan tersebut akan
  * diteruskan. Semua metode yang tidak dikenali akan diteruskan ke
  * penerima (jika penerima meresponsnya, seperti yang tertulis di Forwarder)
  */
  [forwarder hello];

  [recipient release];
  [forwarder release];

  return 0;
}
```


#### Catatan
Saat dikompilasi menggunakan gcc, kompiler melaporkan:

Kompiler melaporkan poin yang disebutkan sebelumnya, bahwa  tidak merespons pesan hello. Dalam situasi ini, peringatan tersebut aman untuk diabaikan karena fitur penerusan telah diimplementasikan. Menjalankan program menghasilkan keluaran ini:

### Kategori
Selama perancangan Objective-C, salah satu perhatian utama adalah pemeliharaan basis kode yang besar. Pengalaman dari dunia pemrograman terstruktur telah menunjukkan bahwa salah satu cara utama untuk meningkatkan kode adalah dengan memecahnya menjadi bagian-bagian yang lebih kecil. Objective-C meminjam dan memperluas konsep *categories* (kategori) dari implementasi Smalltalk untuk membantu proses ini.

[Image showing Objective-C category structure]

Selain itu, metode di dalam kategori ditambahkan ke sebuah kelas pada saat runtime. Dengan demikian, kategori memungkinkan pemrogram untuk menambahkan metode ke kelas yang sudah ada – sebuah kelas terbuka – tanpa perlu mengompilasi ulang kelas tersebut atau bahkan memiliki akses ke kode sumbernya. Sebagai contoh, jika sebuah sistem tidak mengandung pemeriksa ejaan dalam implementasi String-nya, fitur tersebut dapat ditambahkan tanpa memodifikasi kode sumber String.

Metode di dalam kategori menjadi tidak dapat dibedakan dari metode asli dalam sebuah kelas saat program dijalankan. Sebuah kategori memiliki akses penuh ke semua variabel instansi di dalam kelas, termasuk variabel privat.

Jika sebuah kategori mendeklarasikan metode dengan tanda tangan metode yang sama dengan metode yang sudah ada di sebuah kelas, maka metode kategori tersebutlah yang akan diadopsi. Dengan demikian, kategori tidak hanya dapat menambahkan metode ke sebuah kelas, tetapi juga mengganti metode yang sudah ada. Fitur ini dapat digunakan untuk memperbaiki bug di kelas lain dengan menulis ulang metodenya, atau untuk menyebabkan perubahan global pada perilaku kelas dalam sebuah program. Jika dua kategori memiliki metode dengan nama yang sama tetapi tanda tangan metode yang berbeda, maka tidak ditentukan metode dari kategori mana yang akan diadopsi.

Bahasa lain telah mencoba menambahkan fitur ini dengan berbagai cara. Bahasa TOM melangkah lebih jauh dari sistem Objective-C dan mengizinkan penambahan variabel juga. Bahasa lain telah menggunakan solusi berbasis prototipe, yang paling terkenal adalah Self.

Bahasa C# dan Visual Basic (.NET) mengimplementasikan fungsi yang secara dangkal serupa dalam bentuk metode ekstensi, tetapi metode ini tidak memiliki akses ke variabel privat dari kelas tersebut. Ruby dan beberapa bahasa pemrograman dinamis lainnya menyebut teknik ini sebagai "monkey patching".

Logtalk mengimplementasikan konsep kategori (sebagai entitas kelas utama) yang mencakup fungsi kategori Objective-C.

#### Contoh penggunaan kategori
Contoh ini membangun sebuah kelas , dengan mendefinisikan terlebih dahulu kelas dasar dengan hanya metode akses yang diimplementasikan, dan menambahkan dua kategori,  dan , yang memperluas kelas dasar tersebut. Meskipun kategori dapat mengakses anggota data privat kelas dasar, sering kali merupakan praktik yang baik untuk mengakses anggota data privat ini melalui metode akses, yang membantu menjaga kategori tetap lebih independen dari kelas dasar. Mengimplementasikan aksesori tersebut adalah salah satu penggunaan tipikal dari kategori. Kegunaan lainnya adalah menggunakan kategori untuk menambahkan metode ke kelas dasar. Namun, tidak dianggap sebagai praktik yang baik untuk menggunakan kategori guna melakukan penimpaan (*overriding*) subkelas, yang juga dikenal sebagai monkey patching. Protokol informal diimplementasikan sebagai kategori pada kelas dasar . Berdasarkan konvensi, berkas yang berisi kategori yang memperluas kelas dasar akan mengambil nama KelasDasar+KelasEkstensi.h.

; *Integer.h*
:
```objc
#import <objc/Object.h>

@interface Integer : Object {
  int integer;
}

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


; *Integer.m*
:
```objc
#import "Integer.h"

@implementation Integer
- (int) integer {
  return integer;
}

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


; *Integer+Arithmetic.h*
: 
```objc
#import "Integer.h"

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


; *Integer+Arithmetic.m*
: 
```objc
#import "Integer+Arithmetic.h"

@implementation Integer (Arithmetic)
- (id) add: (Integer *) addend {
  return [self integer: [self integer] + [addend integer]];
}

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


; *Integer+Display.h*
: 
```objc
#import "Integer.h"

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


; *Integer+Display.m*
: 
```objc
# import "Integer+Display.h"

@implementation Integer (Display)
- (id) showstars {
  int i, x = [self integer];
  for (i = 0; i < x; i++) {
    printf("*");
  }
  printf("\n");

  return self;
}

- (id) showint {
  printf("%d\n", [self integer]);

  return self;
}
@end
```


; *main.m*
: 
```objc
#import "Integer.h"
#import "Integer+Arithmetic.h"
#import "Integer+Display.h"

int main(void) {
  Integer *num1 = [Integer new], *num2 = [Integer new];
  int x;

  printf("Masukkan sebuah bilangan bulat: ");
  scanf("%d", &x);

  [num1 integer:x];
  [num1 showstars];

  printf("Masukkan sebuah bilangan bulat: ");
  scanf("%d", &x);

  [num2 integer:x];
  [num2 showstars];

  [num1 add:num2];
  [num1 showint];

  return 0;
}
```


#### Catatan
Kompilasi dilakukan, misalnya, dengan:

Seseorang dapat bereksperimen dengan membuang  (baris 2) dan  (baris 21) serta tidak menyertakan  dalam kompilasi. Program akan tetap berjalan. Ini berarti dimungkinkan untuk mencocokkan (*mix-and-match*) kategori yang ditambahkan jika diperlukan; jika sebuah kategori tidak perlu memiliki kemampuan tertentu, kategori tersebut bisa tidak disertakan dalam kompilasi.

### Posing
Objective-C mengizinkan sebuah kelas untuk menggantikan kelas lain sepenuhnya di dalam sebuah program. Kelas pengganti tersebut dikatakan "menyamar sebagai" (*pose as*) kelas target.

Fitur Posing dinyatakan usang (*deprecated*) pada Mac OS X v10.5, dan tidak tersedia dalam runtime 64-bit. Fungsi serupa dapat dicapai dengan menggunakan *method swizzling* dalam kategori, yang menukar implementasi satu metode dengan metode lainnya yang memiliki tanda tangan yang sama.

Untuk versi yang masih mendukung posing, semua pesan yang dikirim ke kelas target justru akan diterima oleh kelas yang menyamar. Ada beberapa batasan:
* Sebuah kelas hanya boleh menyamar sebagai salah satu kelas induk langsung atau tidak langsungnya.
* Kelas yang menyamar tidak boleh mendefinisikan variabel instansi baru yang tidak ada di kelas target (meskipun boleh mendefinisikan atau menimpa metode).
* Kelas target tidak boleh menerima pesan apa pun sebelum posing dilakukan.

Posing, serupa dengan kategori, memungkinkan penambahan global pada kelas yang sudah ada. Posing mengizinkan dua fitur yang tidak ada pada kategori:
* Kelas yang menyamar dapat memanggil metode yang ditimpa melalui super, sehingga menggabungkan implementasi kelas target.
* Kelas yang menyamar dapat menimpa metode yang didefinisikan dalam kategori.

Contoh:


```objc
@interface CustomNSApplication : NSApplication
@end

@implementation CustomNSApplication
- (void) setMainMenu: (NSMenu*) menu {
  // lakukan sesuatu dengan menu
}
@end

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


Ini mencegat setiap pemanggilan setMainMenu ke NSApplication.

### #import
Dalam bahasa C, direktif pra-kompilasi `#include` selalu menyebabkan isi sebuah berkas dimasukkan ke dalam kode sumber pada titik tersebut. Objective-C memiliki direktif `#import`, yang setara kecuali bahwa setiap berkas hanya disertakan sekali per unit kompilasi, sehingga meniadakan kebutuhan akan pelindung sertaan (*include guards*).

Direktif Objective-C ini tidak boleh disamakan dengan kata kunci `import` pada C++, yang digunakan untuk mengimpor modul C++ (sejak C++20), dan bukan merupakan direktif praprosesor. Direktif ini juga tidak boleh disamakan dengan direktif praprosesor `#import` di Microsoft Visual C++ (MSVC), yang bersifat tidak standar dan digunakan untuk mengimpor pustaka tipe.

### Kompilasi Linux gcc


```objc
// BERKAS: hello.m
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
    /* program pertama saya dalam Objective-C */
    NSLog(@"Halo, Dunia! \n");
    return 0;
}
```



```shell-session
$ # Perintah Kompilasi untuk Kompiler gcc dan MinGW:
$ gcc \
    $(gnustep-config --objc-flags) \
    -o hello \
    hello.m \
    -L /GNUstep/System/Library/Libraries \
    -lobjc \
    -lgnustep-base

$ ./hello
```


## Fitur lainnya
Fitur-fitur Objective-C sering kali memungkinkan solusi yang fleksibel dan mudah untuk masalah pemrograman.
* Delegasi metode ke objek lain dan pemanggilan jarak jauh dapat diimplementasikan dengan mudah menggunakan kategori dan penerusan pesan.
* Penyulapan (*swizzling*) pada pointer isa memungkinkan kelas untuk berubah pada saat runtime. Biasanya digunakan untuk pendebugan di mana objek yang telah dibebaskan "disulap" menjadi objek *zombie* yang tugas utamanya hanya melaporkan kesalahan saat seseorang memanggilnya. *Swizzling* juga digunakan dalam Enterprise Objects Framework untuk membuat *fault* basis data. *Swizzling* digunakan saat ini oleh Foundation Framework Apple untuk mengimplementasikan Key-Value Observing.

## Varian bahasa
### Objective-C++
Objective-C++ adalah varian bahasa yang didukung oleh kompiler GNU Compiler Collection dan Clang, yang dapat mengompilasi berkas sumber yang menggunakan kombinasi sintaksis C++ dan Objective-C. Istilah "Objective-C++" dulunya sempat ditampilkan dalam dokumentasi Apple untuk kompiler Objective-C mereka, namun sejak itu telah dihapus.

Objective-C++ menambahkan ekstensi Objective-C ke dalam C++. Karena tidak ada penyatuan semantik di balik berbagai fitur bahasa tersebut, beberapa batasan berlaku:
* Sebuah kelas C++ tidak dapat diturunkan dari kelas Objective-C dan sebaliknya.
* Namespace C++ tidak dapat dideklarasikan di dalam deklarasi Objective-C.
* Deklarasi Objective-C hanya boleh muncul di lingkup global, bukan di dalam namespace C++.
* Kelas Objective-C tidak boleh memiliki variabel instansi berupa Kelas C++ yang tidak memiliki konstruktor default atau yang memiliki satu atau lebih metode virtual, namun pointer ke objek C++ dapat digunakan sebagai variabel instansi tanpa batasan (alokasikan dengan kata kunci *new* di dalam metode -init).
* Semantik C++ "berdasarkan nilai" (*by value*) tidak dapat diterapkan pada objek Objective-C, yang hanya dapat diakses melalui pointer.
* Deklarasi Objective-C tidak boleh berada di dalam deklarasi templat C++ dan sebaliknya. Namun, tipe Objective-C (misalnya, ) dapat digunakan sebagai parameter templat C++.
* Penanganan pengecualian Objective-C dan C++ berbeda; penangan masing-masing tidak dapat menangani pengecualian tipe lainnya. Akibatnya, destruktor objek tidak dijalankan. Hal ini dimitigasi dalam runtime "Objective-C 2.0" terbaru karena pengecualian Objective-C digantikan oleh pengecualian C++ sepenuhnya (runtime Apple), atau sebagian saat pustaka Objective-C++ ditautkan (GNUStep libobjc2).
* Blok Objective-C dan lambda C++11 adalah entitas yang berbeda. Namun, sebuah blok akan dibuat secara otomatis di macOS saat memasukkan lambda di tempat yang mengharapkan sebuah blok.

### Objective-C 2.0
Pada Worldwide Developers Conference 2006, Apple mengumumkan rilis "Objective-C 2.0," sebuah revisi bahasa Objective-C untuk menyertakan "pengumpulan sampah modern, peningkatan sintaksis, peningkatan kinerja runtime, dan dukungan 64-bit". Mac OS X v10.5, yang dirilis pada Oktober 2007, menyertakan kompiler Objective-C 2.0. GCC 4.6 mendukung banyak fitur baru Objective-C, seperti properti yang dideklarasikan dan disintesis, sintaksis titik (*dot syntax*), enumerasi cepat (*fast enumeration*), metode protokol opsional, atribut kelas/protokol/metode, ekstensi kelas, dan API runtime GNU Objective-C baru.

Pemberian nama Objective-C 2.0 mewakili perubahan dalam sistem penomoran versi bahasa tersebut, karena versi Objective-C terakhir untuk NeXT adalah "objc4". Nama proyek ini tetap dipertahankan dalam rilis terakhir kode sumber runtime Objective-C lama di Mac OS X Leopard (10.5).

#### Pengumpulan sampah
Objective-C 2.0 menyediakan fitur opsional pengumpul sampah (*garbage collector*) generasional yang konservatif. Saat dijalankan dalam mode kompatibilitas mundur, runtime mengubah operasi penghitungan referensi seperti "retain" dan "release" menjadi operasi kosong (*no-ops*). Semua objek menjadi subjek pengumpulan sampah saat fitur ini diaktifkan. Pointer C biasa dapat dikualifikasi dengan "__strong" untuk memicu intersepsi kompiler dan berpartisipasi dalam pengumpulan sampah. Sistem *weak subsystem* juga disediakan sehingga pointer yang ditandai sebagai "__weak" disetel ke nol saat objek dikumpulkan. Pengumpul sampah ini tidak ada pada implementasi Objective-C 2.0 di iOS. Pengumpulan sampah dalam Objective-C berjalan pada utas latar belakang prioritas rendah.

Pengumpulan sampah dinyatakan usang (*deprecated*) pada Mac OS X v10.8 demi Penghitungan Referensi Otomatis (ARC). Objective-C pada iOS 7 yang berjalan di ARM64 menggunakan 19 bit dari kata 64-bit untuk menyimpan hitungan referensi, sebagai bentuk dari pointer bertanda.

#### Properti
Objective-C 2.0 memperkenalkan sintaksis baru untuk mendeklarasikan variabel instansi sebagai properti, dengan atribut opsional untuk mengatur pembuatan metode akses. Properti, dalam arti tertentu, adalah variabel instansi publik; artinya, mendeklarasikan variabel instansi sebagai properti memberikan akses kepada kelas eksternal terhadap properti tersebut. Properti dapat dideklarasikan sebagai "readonly", dan dapat diberikan semantik penyimpanan seperti `assign`, `copy`, atau `retain`. Secara default, properti dianggap `atomic`, yang menghasilkan penguncian (*lock*) untuk mencegah banyak utas mengaksesnya secara bersamaan. Properti dapat dideklarasikan sebagai `nonatomic` untuk menghapus penguncian ini.


```objc
@interface Person : NSObject {
@public
  NSString *name;
@private
  int age;
}

@property(copy) NSString *name;
@property(readonly) int age;

- (id)initWithAge:(int)age;
@end
```
Properti diimplementasikan dengan kata kunci `@synthesize`, yang menghasilkan metode *getter* (dan *setter*, jika bukan baca-saja). Cara lainnya, metode *getter* dan *setter* harus diimplementasikan secara eksplisit, atau kata kunci `@dynamic` dapat digunakan untuk menunjukkan bahwa metode akses akan disediakan dengan cara lain. Saat dikompilasi menggunakan clang 3.1 atau lebih tinggi, semua properti yang tidak dideklarasikan secara eksplisit dengan `@dynamic` akan secara otomatis di-`@synthesize` secara implisit.


```objc
@implementation Person
@synthesize name;

- (id)initWithAge:(int)initAge {
  self = [super init];
  if (self) {
    // CATATAN: penetapan variabel instansi langsung, bukan properti setter
    age = initAge;
  }
  return self;
}

- (int)age {
  return age;
}
@end
```


Properti dapat diakses menggunakan sintaksis pengiriman pesan tradisional, notasi titik (*dot notation*), atau dalam Key-Value Coding.

#### Variabel instansi tidak rapuh
Objective-C 2.0 menyediakan variabel instansi "tidak rapuh" (*non-fragile*) di mana didukung oleh runtime (misalnya pada macOS 64-bit dan semua iOS). Di bawah runtime modern, lapisan tambahan ditambahkan pada akses variabel instansi, memungkinkan linker dinamis untuk menyesuaikan tata letak instansi saat runtime. Fitur ini memungkinkan dua peningkatan penting:
* Menghilangkan Masalah antarmuka biner rapuh; kelas induk dapat mengubah ukuran tanpa memengaruhi kompatibilitas biner.
* Memungkinkan variabel instansi yang menjadi pendukung properti untuk disintesis saat runtime tanpa harus dideklarasikan di antarmuka kelas.

#### Enumerasi cepat
Alih-alih menggunakan objek NSEnumerator atau indeks untuk melakukan iterasi melalui koleksi, Objective-C 2.0 menawarkan sintaksis enumerasi cepat (*fast enumeration*). Di bawah ini adalah perbandingannya:


```objc
// Menggunakan enumerasi cepat
for (Person *p in thePeople) {
  NSLog(@"%@ berumur %i tahun.", [p name], [p age]);
}
```
Enumerasi cepat menghasilkan kode yang lebih efisien daripada enumerasi standar karena pemanggilan metode untuk mengenumerasi objek digantikan oleh aritmetika pointer menggunakan protokol NSFastEnumeration.

#### Ekstensi kelas
Ekstensi kelas memiliki sintaksis yang sama dengan deklarasi kategori tanpa nama kategori, dan metode serta properti yang dideklarasikan di dalamnya ditambahkan langsung ke kelas utama. Ini sebagian besar digunakan sebagai alternatif kategori untuk menambahkan metode ke kelas tanpa mempublikasikannya di header publik.

### Blok

Blok (*Blocks*) adalah ekstensi non-standar untuk Objective-C (juga C dan C++) yang menggunakan sintaksis khusus untuk membuat penutupan (*closures*). Blok hanya didukung pada Mac OS X 10.6 atau lebih baru, dan iOS 4 atau lebih baru.

### Automatic Reference Counting

Automatic Reference Counting (ARC) adalah fitur waktu kompilasi yang menghilangkan kebutuhan pemrogram untuk mengelola hitungan referensi secara manual menggunakan `retain` dan `release`. Berbeda dengan pengumpulan sampah, ARC menghilangkan beban proses terpisah karena manajemen dilakukan saat kompilasi.

#### Literal
Runtime Obj-C NeXT dan Apple telah lama menyertakan cara singkat untuk membuat string baru menggunakan sintaksis literal `@"sebuah string"`. Saat menggunakan kompiler Apple LLVM 4.0 atau lebih baru, array, kamus, dan angka juga dapat dibuat menggunakan sintaksis literal.

Contoh dengan literal:

```objc
NSArray *myArray = @[ object1, object2, object3 ];
NSDictionary *myDictionary = @{ @"key" : someObject };
NSNumber *myNumber = @(myInt);
```

#### Subskripsi
Array dan kamus dapat dimanipulasi menggunakan subskripsi (*subscripting*) dengan kurung siku `[ ]`.


```objc
id object1 = someArray[0];
id object2 = someDictionary[@"key"];
someMutableArray[0] = object3;
```


### Clang
Rangkaian kompiler Clang, bagian dari proyek LLVM, mengimplementasikan Objective-C dan bahasa lainnya. Setelah GCC 4.3 beralih ke GPLv3, Apple meninggalkannya demi Clang. Akibatnya, banyak fitur bahasa Objective-C modern hanya didukung oleh Clang.

### GNU, GNUstep, dan WinObjC
Proyek GNU telah lama tertarik pada platform untuk mem-porting program NeXT dan Obj-C. Pengembang GNUstep yang tertarik pada bahasa baru melakukan percabangan (*fork*) terhadap libobjc GCC menjadi proyek independen yang disebut  pada tahun 2009.

Microsoft melakukan percabangan terhadap runtime ObjFW menjadi bagian dari WinObjC, jembatan iOS untuk Universal Windows Platform, pada tahun 2015. Proyek ini memungkinkan penggunaan kembali kode aplikasi iOS di dalam aplikasi UWP Windows.

Di Windows, peralatan pengembangan Objective-C disediakan di situs web GNUstep, yang terdiri dari sistem GNUstep MSYS, Core, dan IDE ProjectCenter.

## Penggunaan pustaka
Objective-C saat ini sering digunakan bersamaan dengan pustaka objek standar tetap (sering dikenal sebagai "kit" atau "framework"), seperti Cocoa, GNUstep, atau ObjFW. Pustaka-pustaka ini sering kali disertakan dalam sistem operasi: pustaka GNUstep sering kali disertakan dalam distribusi berbasis Linux, dan Cocoa disertakan dalam macOS. Pemrogram tidak dipaksa untuk mewarisi fungsi dari kelas dasar yang sudah ada (NSObject – OFObject). Objective-C memungkinkan deklarasi kelas akar (*root class*) baru yang tidak mewarisi fungsi apa pun yang sudah ada. Awalnya, lingkungan pemrograman berbasis Objective-C biasanya menawarkan kelas  sebagai kelas dasar yang diwarisi oleh hampir semua kelas lainnya. Dengan diperkenalkannya OpenStep, NeXT membuat kelas dasar baru bernama , yang menawarkan fitur tambahan dibandingkan  (misalnya, penekanan pada penggunaan referensi objek dan penghitungan referensi alih-alih pointer mentah). Hampir semua kelas dalam Cocoa mewarisi dari .

Penamaan ulang tersebut tidak hanya berfungsi untuk membedakan perilaku default baru dari kelas-kelas dalam OPENSTEP API, tetapi juga memungkinkan kode yang menggunakan —kelas dasar asli yang digunakan pada NeXTSTEP (dan, kurang lebih, pustaka kelas Objective-C lainnya)—untuk hidup berdampingan dalam runtime yang sama dengan kode yang menggunakan  (dengan beberapa batasan). Pengenalan awalan dua huruf juga menjadi bentuk sederhana dari namespace, yang tidak dimiliki oleh Objective-C. Menggunakan awalan (*prefix*) untuk membuat pengidentifikasi paket informal menjadi standar pengkodean informal dalam komunitas Objective-C, dan terus berlanjut hingga hari ini.

Baru-baru ini, manajer paket mulai bermunculan, seperti CocoaPods, yang bertujuan untuk menjadi manajer paket sekaligus repositori paket. Banyak kode Objective-C sumber terbuka yang ditulis dalam beberapa tahun terakhir kini dapat dipasang menggunakan CocoaPods.

## Analisis bahasa
Implementasi Objective-C menggunakan sistem runtime tipis yang ditulis dalam C, yang memberikan sedikit tambahan pada ukuran aplikasi. Sebaliknya, sebagian besar sistem berorientasi objek pada saat bahasa ini diciptakan menggunakan runtime virtual machine yang besar. Program yang ditulis dalam Objective-C cenderung tidak jauh lebih besar dari ukuran kode mereka dan pustaka-pustakanya (yang umumnya tidak perlu disertakan dalam distribusi perangkat lunak), berbeda dengan sistem Smalltalk di mana memori dalam jumlah besar digunakan hanya untuk membuka sebuah jendela. Aplikasi Objective-C cenderung lebih besar daripada aplikasi C atau C++ yang serupa karena pengetikan dinamis Objective-C tidak memungkinkan metode untuk dihapus (*stripped*) atau dimasukkan secara segaris (*inlined*). Karena pemrogram memiliki kebebasan untuk mendelegasikan, meneruskan panggilan, membangun selektor secara cepat, dan meneruskannya ke sistem runtime, kompiler Objective-C tidak dapat berasumsi bahwa aman untuk menghapus metode yang tidak digunakan atau melakukan *inline calls*.

Demikian pula, bahasa ini dapat diimplementasikan di atas kompiler C yang sudah ada (dalam GCC, pertama sebagai praprosesor, kemudian sebagai modul) alih-alih sebagai kompiler baru. Hal ini memungkinkan Objective-C untuk memanfaatkan koleksi kode C, pustaka, dan peralatan yang sudah ada. Pustaka C yang ada dapat dibungkus dalam pembungkus (wrapper) Objective-C untuk menyediakan antarmuka bergaya OO (orientasi objek). Dalam aspek ini, Objective-C mirip dengan pustaka GObject dan bahasa Vala, yang banyak digunakan dalam pengembangan aplikasi GTK.

Semua perubahan praktis ini menurunkan hambatan masuk, yang kemungkinan merupakan masalah terbesar bagi penerimaan luas Smalltalk pada tahun 1980-an.

Kritik umum yang sering muncul adalah bahwa Objective-C tidak memiliki dukungan bahasa untuk namespace. Sebaliknya, pemrogram terpaksa menambahkan awalan (*prefix*) pada nama kelas mereka, yang secara tradisional lebih pendek daripada nama namespace sehingga lebih rentan terhadap bentrokan (*collision*). Hingga tahun 2007, semua kelas dan fungsi macOS dalam lingkungan pemrograman Cocoa diberi awalan "NS" (misalnya NSObject, NSButton) untuk mengidentifikasi bahwa mereka milik inti macOS atau iOS; "NS" berasal dari nama kelas yang ditentukan selama pengembangan NeXTSTEP.

Karena Objective-C adalah superset ketat dari C, ia tidak memperlakukan tipe primitif C sebagai objek warga kelas satu.

Berbeda dengan C++, Objective-C tidak mendukung kelebihan beban operator (*operator overloading*). Juga tidak seperti C++, Objective-C mengizinkan sebuah objek untuk mewarisi secara langsung hanya dari satu kelas (melarang pewarisan jamak). Namun, dalam kebanyakan kasus, kategori dan protokol dapat digunakan sebagai cara alternatif untuk mencapai hasil yang sama.

Karena Objective-C menggunakan pengetikan runtime dinamis dan karena semua pemanggilan metode adalah pemanggilan fungsi (atau, dalam beberapa kasus, panggilan sistem), banyak optimasi kinerja umum tidak dapat diterapkan pada metode Objective-C (misalnya: *inlining*, propagasi konstanta, optimasi antarprosedur, dan penggantian skalar agregat). Hal ini membatasi kinerja abstraksi Objective-C dibandingkan dengan abstraksi serupa dalam bahasa seperti C++ di mana optimasi tersebut dimungkinkan.

### Manajemen memori
Versi pertama Objective-C tidak mendukung pengumpulan sampah (*garbage collection*). Pada saat itu, keputusan ini menjadi bahan perdebatan, dan banyak orang menganggap "waktu mati" yang lama (saat Smalltalk melakukan pengumpulan) membuat seluruh sistem tidak dapat digunakan. Beberapa implementasi pihak ketiga telah menambahkan fitur ini (terutama GNUstep menggunakan Boehm), dan Apple telah mengimplementasikannya sejak Mac OS X v10.5. Namun, pada versi terbaru macOS dan iOS, pengumpulan sampah telah ditinggalkan demi Penghitungan Referensi Otomatis (ARC), yang diperkenalkan pada tahun 2011.

Dengan ARC, kompiler menyisipkan pemanggilan *retain* dan *release* secara otomatis ke dalam kode Objective-C berdasarkan analisis kode statis. Otomatisasi ini membebaskan pemrogram dari keharusan menulis kode manajemen memori. ARC juga menambahkan referensi lemah (*weak references*) ke dalam bahasa Objective-C.

### Perbedaan filosofis antara Objective-C dan C++
Desain dan implementasi C++ dan Objective-C mewakili pendekatan yang secara fundamental berbeda dalam memperluas C.

Selain gaya pemrograman prosedural milik C, C++ secara langsung mendukung bentuk-bentuk tertentu dari pemrograman berorientasi objek, pemrograman generik, dan metapemrograman. C++ juga dilengkapi dengan pustaka standar yang besar yang mencakup beberapa kelas kontainer. Demikian pula, Objective-C menambahkan pemrograman berorientasi objek, pengetikan dinamis, dan refleksi ke dalam C. Objective-C tidak menyediakan pustaka standar *per se*, tetapi di sebagian besar tempat di mana Objective-C digunakan, ia digunakan dengan pustaka bergaya OpenStep seperti OPENSTEP, Cocoa, atau GNUstep, yang menyediakan fungsi yang mirip dengan pustaka standar C++.

Salah satu perbedaan yang mencolok adalah bahwa Objective-C menyediakan dukungan runtime untuk fitur pemrograman reflektif, sedangkan C++ hanya menambahkan sedikit dukungan runtime pada C. Dalam Objective-C, sebuah objek dapat ditanyai tentang propertinya sendiri, misalnya, apakah ia akan merespons pesan tertentu. Dalam C++, hal ini tidak dimungkinkan tanpa penggunaan pustaka eksternal.

Penggunaan refleksi adalah bagian dari perbedaan yang lebih luas antara fitur dinamis (saat runtime) dan fitur statis (saat kompilasi) dari suatu bahasa. Meskipun Objective-C dan C++ masing-masing menggunakan campuran dari kedua fitur tersebut, Objective-C lebih menyukai keputusan saat runtime sementara C++ lebih menyukai keputusan saat kompilasi. Ketegangan antara pemrograman dinamis dan statis melibatkan banyak pengorbanan klasik dalam pemrograman: fitur dinamis menambah fleksibilitas, fitur statis menambah kecepatan dan pengecekan tipe.

Pemrograman generik dan metapemrograman dapat diimplementasikan di kedua bahasa menggunakan polimorfisme runtime (dynamic dispatch). Dalam C++, hal ini mengambil bentuk fungsi virtual dan runtime type identification, sementara Objective-C menawarkan pengetikan dinamis dan refleksi. Baik Objective-C maupun C++ mendukung polimorfisme waktu kompilasi (fungsi generik), di mana Objective-C menambahkan fitur ini pada tahun 2015.

## Lihat pula
* C (bahasa pemrograman)
* C++
* CocoaPods
* Perbandingan bahasa pemrograman
* GNUStep
* Perbandingan dengan COM, GObject, SOM, Windows Runtime, XPCOM
* Swift (bahasa pemrograman)
* Xcode
* WinObjC (alias: Windows Bridge for iOS)

## Referensi

## Bacaan lebih lanjut

* 

## Pranala luar

* Programming with Objective-C, dari Apple (13-12-2012)
* *[https://developer.apple.com/legacy/library/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html The Objective-C Programming Language]*, dari Apple (11-10-2011)
* *[https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Introduction/Introduction.html Objective-C Runtime Programming Guide]*, dari Apple (19-10-2009)
* Objective-C GNUstep Base Programming Manual
* Objective-C oleh Brad Cox
* FAQ Objective-C
* Contoh Objective-C ()