Objective-C
| Paradigmas | Reflektif, berbasis kelas, berorientasi objek |
|---|---|
| Keluarga | C |
| Dirancang oleh | Brad Cox, Tom Love |
| Pertama kali muncul | 1984 |
| Rilis stabil | 2.0[1]
|
| Tata tertib penjenisan | Statis, dinamis, lemah |
| SO | Lintas platform |
| Ekstensi nama berkas | .h, .m, .mm, .M |
| Situs web | developer.apple.com |
| Pelaksanaan utama | |
| Clang, GCC | |
| Dipengaruhi oleh | |
| C, Smalltalk | |
| Memengaruhi | |
| Groovy, Java, Nu, Objective-J, TOM,Swift[2] | |
| |
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.[3] 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,[4] 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.[5]
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 .m, sedangkan berkas 'header/interface' Objective-C memiliki ekstensi .h, sama seperti berkas header C. Berkas Objective-C++ ditandai dengan ekstensi nama berkas .mm.
Sejarah
[sunting | sunting sumber]Objective-C diciptakan terutama oleh Brad Cox dan Tom Love pada awal 1980-an di perusahaan mereka, Productivity Products International (PPI).[6]
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.[7] 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.[8]
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).[9]
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
[sunting | sunting sumber]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.[10]
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.[11] 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.[12]
Pengembangan Apple dan Swift
[sunting | sunting sumber]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
[sunting | sunting sumber]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.[13][14][15][16][17][18]
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
[sunting | sunting sumber]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 SEL — pengenal unik untuk setiap nama pesan, seringkali berupa NUL-terminated string yang mewakili namanya—dan diselesaikan menjadi sebuah pointer metode C yang mengimplementasikannya: sebuah IMP.[19] 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).[20]
Mengirim pesan method ke objek yang ditunjuk oleh pointer obj akan memerlukan kode berikut dalam C++:
obj->method(argument);
Dalam Objective-C, hal ini ditulis sebagai berikut:
[obj method:argument];
Pemanggilan "method" tersebut diterjemahkan oleh kompiler ke keluarga fungsi runtime objc_msgSend(id self, SEL op, ...). Implementasi yang berbeda menangani tambahan modern seperti super.[21] Dalam keluarga GNU, fungsi ini dinamakan objc_msg_sendv, namun telah ditinggalkan demi sistem pencarian modern di bawah objc_msg_lookup.[22]
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
[sunting | sunting sumber]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
[sunting | sunting sumber]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 Bola.h akan berisi antarmuka untuk kelas Bola.
Deklarasi antarmuka mengambil bentuk sebagai berikut:
@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:
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 metodeInstansi2Dengan2Parameter:namaPanggilParam2: 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 id.
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.
- (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.[23]
Implementasi
[sunting | sunting sumber]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).[24]
@implementation namakelas
+ (tipe_kembalian)metodeKelas {
// implementasi
}
- (tipe_kembalian)metodeInstansi {
// implementasi
}
@end
Metode ditulis menggunakan deklarasi antarmukanya. Perbandingan antara Objective-C dan C:
- (int)method:(int)i {
return [self square_root:i];
}
int function(int i) {
return square_root(i);
}
Sintaksis ini memungkinkan pemberian nama semu pada argumen.
- (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 Warna, metode instansi -ubahWarnaKeMerah:hijau:biru: mungkin secara internal dilabeli _i_Warna_ubahWarnaKeMerah_hijau_biru. Huruf i 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
[sunting | sunting sumber]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:
MyObject *foo = [[MyObject alloc] init];
Instansiasi dengan penginisialisasi khusus:
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:
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:
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:
- (id)init {
self = [super init];
if (self) {
// lakukan inisialisasi objek di sini
}
return self;
}
Pada contoh di atas, perhatikan tipe kembalian id. 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
initke instansi kelas induk dan memberikan hasilnya keself(pointer ke objek saat ini).
- Mengirim pesan
- 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 nil; pernyataan kondisional seperti if memperlakukan nil seperti pointer null, sehingga kode inisialisasi tidak akan dieksekusi jika [super init] mengembalikan nil. Jika terjadi kesalahan dalam inisialisasi, metode init harus melakukan pembersihan yang diperlukan, termasuk mengirim pesan release ke self, dan mengembalikan nil 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
[sunting | sunting sumber]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:
@protocol NSLocking
- (void)lock;
- (void)unlock;
@end
menunjukkan bahwa terdapat ide abstrak tentang penguncian (locking). Dengan menyatakan dalam definisi kelas bahwa protokol tersebut diimplementasikan:
@interface NSLock : NSObject <NSLocking>
// ...
@end
instansi dari NSLock menyatakan bahwa mereka akan menyediakan implementasi untuk kedua metode instansi tersebut.
Pengetikan dinamis
[sunting | sunting sumber]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).[25] 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.
- (void)setMyValue:(id)foo;
Dalam pernyataan di atas, foo dapat berupa kelas apa pun.
- (void)setMyValue:(id<NSCopying>)foo;
Dalam pernyataan di atas, foo dapat berupa instansi dari kelas apa pun yang mematuhi protokol NSCopying.
- (void)setMyValue:(NSNumber *)foo;
Dalam pernyataan di atas, foo harus merupakan instansi dari kelas NSNumber.
- (void)setMyValue:(NSNumber<NSCopying> *)foo;
Dalam pernyataan di atas, foo harus merupakan instansi dari kelas NSNumber, dan harus mematuhi protokol NSCopying.
Dalam Objective-C, semua objek direpresentasikan sebagai pointer, dan inisialisasi statis tidak diperbolehkan. Objek yang paling sederhana adalah tipe yang ditunjuk oleh (Tatar) ((Tatar)), 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
[sunting | sunting sumber]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 Object
- metode penerusan:
- (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:
- (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 performv:: 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 Object. Metode - (void)forwardInvocation:(NSInvocation *)anInvocation dari kelas NSObject digunakan untuk melakukan penerusan.
Contoh
[sunting | sunting sumber]Berikut adalah contoh program yang mendemonstrasikan dasar-dasar penerusan (forwarding).
- Forwarder.h
#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
#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
#import <objc/Object.h>
// Objek Penerima sederhana.
@interface Recipient : Object
- (id)hello;
@end
- Recipient.m
#import "Recipient.h"
@implementation Recipient
- (id)hello {
printf("Penerima mengatakan halo!\n");
return self;
}
@end
- main.m
#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
[sunting | sunting sumber]Saat dikompilasi menggunakan gcc, kompiler melaporkan:
$ gcc -x objective-c -Wno-import Forwarder.m Recipient.m main.m -lobjc
main.m: In function `main':
main.m:12: warning: `Forwarder' does not respond to `hello'
$
Kompiler melaporkan poin yang disebutkan sebelumnya, bahwa Forwarder tidak merespons pesan hello. Dalam situasi ini, peringatan tersebut aman untuk diabaikan karena fitur penerusan telah diimplementasikan. Menjalankan program menghasilkan keluaran ini:
$ ./a.out
Penerima mengatakan halo!
Kategori
[sunting | sunting sumber]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.[26]
[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.[27] 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
[sunting | sunting sumber]Contoh ini membangun sebuah kelas Integer, dengan mendefinisikan terlebih dahulu kelas dasar dengan hanya metode akses yang diimplementasikan, dan menambahkan dua kategori, Arithmetic dan Display, 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 NSObject. Berdasarkan konvensi, berkas yang berisi kategori yang memperluas kelas dasar akan mengambil nama KelasDasar+KelasEkstensi.h.
- Integer.h
#import <objc/Object.h> @interface Integer : Object { int integer; } - (int)integer; - (id)integer:(int)_integer; @end
- Integer.m
#import "Integer.h" @implementation Integer - (int) integer { return integer; } - (id) integer: (int) _integer { integer = _integer; return self; } @end
- Integer+Arithmetic.h
#import "Integer.h" @interface Integer (Arithmetic) - (id) add: (Integer *) addend; - (id) sub: (Integer *) subtrahend; @end
- Integer+Arithmetic.m
#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
#import "Integer.h" @interface Integer (Display) - (id) showstars; - (id) showint; @end
- Integer+Display.m
# 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
#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
[sunting | sunting sumber]Kompilasi dilakukan, misalnya, dengan:
$ gcc -x objective-c main.m Integer.m Integer+Arithmetic.m Integer+Display.m -lobjc
Seseorang dapat bereksperimen dengan membuang #import "Integer+Arithmetic.h" (baris 2) dan [num1 add:num2] (baris 21) serta tidak menyertakan Integer+Arithmetic.m 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
[sunting | sunting sumber]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:
@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
[sunting | sunting sumber]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.[28]
Kompilasi Linux gcc
[sunting | sunting sumber]// 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;
}
$ # 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
[sunting | sunting sumber]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
[sunting | sunting sumber]Objective-C++
[sunting | sunting sumber]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.[29]
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,
NamaKelas *) 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).[30]
- 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.[31]
Objective-C 2.0
[sunting | sunting sumber]Pada Worldwide Developers Conference 2006, Apple mengumumkan rilis "Objective-C 2.0," sebuah revisi bahasa Objective-C untuk menyertakan "pengumpulan sampah modern, peningkatan sintaksis,[32] peningkatan kinerja runtime,[33] 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.[34]
Pemberian nama Objective-C 2.0 mewakili perubahan dalam sistem penomoran versi bahasa tersebut, karena versi Objective-C terakhir untuk NeXT adalah "objc4".[35] Nama proyek ini tetap dipertahankan dalam rilis terakhir kode sumber runtime Objective-C lama di Mac OS X Leopard (10.5).
Pengumpulan sampah
[sunting | sunting sumber]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).[36] 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
[sunting | sunting sumber]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.
@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.
@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
[sunting | sunting sumber]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
[sunting | sunting sumber]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:
// 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.[37]
Ekstensi kelas
[sunting | sunting sumber]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
[sunting | sunting sumber]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
[sunting | sunting sumber]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
[sunting | sunting sumber]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:
NSArray *myArray = @[ object1, object2, object3 ];
NSDictionary *myDictionary = @{ @"key" : someObject };
NSNumber *myNumber = @(myInt);
Subskripsi
[sunting | sunting sumber]Array dan kamus dapat dimanipulasi menggunakan subskripsi (subscripting) dengan kurung siku [ ].
id object1 = someArray[0];
id object2 = someDictionary[@"key"];
someMutableArray[0] = object3;
Clang
[sunting | sunting sumber]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
[sunting | sunting sumber]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 (Tatar) 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
[sunting | sunting sumber]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 Object sebagai kelas dasar yang diwarisi oleh hampir semua kelas lainnya. Dengan diperkenalkannya OpenStep, NeXT membuat kelas dasar baru bernama NSObject, yang menawarkan fitur tambahan dibandingkan Object (misalnya, penekanan pada penggunaan referensi objek dan penghitungan referensi alih-alih pointer mentah). Hampir semua kelas dalam Cocoa mewarisi dari NSObject.
Penamaan ulang tersebut tidak hanya berfungsi untuk membedakan perilaku default baru dari kelas-kelas dalam OPENSTEP API, tetapi juga memungkinkan kode yang menggunakan Object—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 NSObject (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
[sunting | sunting sumber]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
[sunting | sunting sumber]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.[38] 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.[39]
Perbedaan filosofis antara Objective-C dan C++
[sunting | sunting sumber]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
[sunting | sunting sumber]Referensi
[sunting | sunting sumber]- ↑ "Runtime Versions and Platforms". Developer.apple.com. Diarsipkan dari versi aslinya tanggal July 20, 2016. Diakses tanggal December 24, 2017.
- ↑ Lattner, Chris (June 3, 2014). "Chris Lattner's Homepage". Chris Lattner. Diarsipkan dari versi aslinya tanggal June 4, 2014. Diakses tanggal June 3, 2014.
Bahasa Swift adalah produk dari upaya tanpa lelah dari tim ahli bahasa, pakar dokumentasi, ninja optimasi kompiler, dan grup dogfooding internal yang sangat penting yang memberikan umpan balik untuk membantu menyempurnakan dan menguji ide-ide dalam pertempuran. Tentu saja, ia juga sangat diuntungkan dari pengalaman yang dimenangkan dengan susah payah oleh banyak bahasa lain di lapangan, menarik ide-ide dari Objective-C, Rust, Haskell, Ruby, Python, C#, CLU, dan terlalu banyak bahasa lain untuk disebutkan.
- ↑ Apple Developer (2013-04-23). "The Objective-C Programming Language (Introduction)". Apple Inc. Diarsipkan dari versi aslinya tanggal 2018-10-26. Diakses tanggal 2025-02-15.
- ↑ Singh, Amit (December 2003). "A Brief History of Mac OS X". Mac OS X Internals. Diarsipkan dari versi aslinya tanggal May 14, 2012. Diakses tanggal June 11, 2012.
- ↑ "App Frameworks". Apple. June 2014. Diarsipkan dari versi aslinya tanggal February 16, 2019. Diakses tanggal February 13, 2019.
- ↑ Garling, Caleb. "iPhone Coding Language Now World's Third Most Popular". Wired. Diarsipkan dari versi aslinya tanggal September 9, 2013. Diakses tanggal May 20, 2013.
- ↑ Wentk, Richard (2009). Cocoa: Volume 5 of Developer Reference Apple Developer Series. John Wiley and Sons. ISBN 978-0-470-49589-6. Diarsipkan dari versi aslinya tanggal February 16, 2017. Diakses tanggal July 22, 2016.
- ↑ Biancuzzi, Federico; Warden, Shane (2009). Masterminds of Programming. O'Reilly Media, Inc. hlm. 242–246. ISBN 978-0-596-51517-1. Diarsipkan dari versi aslinya tanggal February 17, 2017. Diakses tanggal July 22, 2016.
- ↑ Cox, Brad (1983). "The object oriented pre-compiler: programming Smalltalk-80 methods in C language". ACM SIGPLAN Notices. 18 (1). New York, NY: ACM. doi:10.1145/948093.948095. S2CID 6975032. Diakses tanggal February 17, 2011.
- ↑ "Common Lisp and Readline". GitHub. Diarsipkan dari versi aslinya tanggal September 6, 2014. Diakses tanggal September 15, 2014.
Masalah ini pertama kali muncul ketika NeXT mengusulkan untuk mendistribusikan GCC yang dimodifikasi dalam dua bagian dan membiarkan pengguna menghubungkannya. Jobs bertanya kepada saya apakah ini sah menurut hukum. Bagi saya saat itu tampak sah, mengikuti penalaran seperti yang Anda gunakan; tetapi karena hasilnya sangat tidak diinginkan bagi perangkat lunak bebas, saya katakan saya harus bertanya kepada pengacara. Apa yang dikatakan pengacara itu mengejutkan saya; dia mengatakan bahwa hakim akan menganggap skema seperti itu sebagai "dalih" dan akan sangat keras terhadap mereka. Dia mengatakan seorang hakim akan bertanya apakah itu "benar-benar" satu program, bukan bagaimana labelnya. Jadi saya kembali ke Jobs dan mengatakan kami yakin rencananya tidak diizinkan oleh GPL. Hasil langsung dari ini adalah sekarang kita memiliki frontend Objective-C. Mereka ingin mendistribusikan parser Objective C sebagai paket kepemilikan terpisah untuk dihubungkan dengan backend GCC, tetapi karena saya tidak setuju ini diizinkan, mereka menjadikannya bebas.
- ↑ "GNUstep: Introduction". GNUstep developers/GNU Project. Diarsipkan dari versi aslinya tanggal August 6, 2012. Diakses tanggal July 29, 2012.
- ↑ "Kresten Krab Thorup | LinkedIn". www.linkedin.com. Diarsipkan dari versi aslinya tanggal July 15, 2014. Diakses tanggal June 23, 2016.
- ↑ "Write Objective-C Code". apple.com. April 23, 2013. Diarsipkan dari versi aslinya tanggal December 24, 2013. Diakses tanggal December 22, 2013.
- ↑ "Objective-C Boot Camp". Diarsipkan dari versi aslinya tanggal February 11, 2018. Diakses tanggal February 11, 2018.
Objective-C is a strict superset of ANSI C
- ↑ "Examining Objective-C". Dr. Dobb's. Diarsipkan dari versi aslinya tanggal September 4, 2014. Diakses tanggal September 4, 2014.
Objective-C is an object-oriented strict superset of C
- ↑ Lee, Keith (September 3, 2013). Pro Objective-C. Apress. ISBN 9781430250500. Diarsipkan dari versi aslinya tanggal May 14, 2018. Diakses tanggal December 24, 2017 – via Google Books.
- ↑ "Tags for Objective-C Headers". Diarsipkan dari versi aslinya tanggal April 1, 2017. Diakses tanggal February 11, 2018.
Objective-C is a superset of C
- ↑ "AppScan Source 8.7 now available". July 11, 2014. Diarsipkan dari versi aslinya tanggal February 3, 2017. Diakses tanggal February 11, 2018.
The Objective-C programming language is a superset of the C programming language
- ↑ Apple, Inc. (October 19, 2009). "Dynamic Method Resolution". Objective-C Runtime Programming Guide. Diarsipkan dari versi aslinya tanggal September 7, 2010. Diakses tanggal November 25, 2014.
- ↑ Apple, Inc. (October 19, 2009). "Avoiding Messaging Errors". The Objective-C Programming Language. Diarsipkan dari asli tanggal September 8, 2010.
- ↑ "objc_msgSend - Objective-C Runtime". Apple Developer Documentation. Diakses tanggal 10 February 2020.
- ↑ "Messaging with the GNU Objective-C runtime". Using the GNU Compiler Collection (GCC). Diakses tanggal 10 February 2020.
- ↑ "Category". Apple Developer (Cocoa Core Competencies).
- ↑ Dalrymple, Mark; Knaster, Scott (June 27, 2012). Learn Objective-C on the Mac. Apress. hlm. 9. ISBN 9781430241881.
Ekstensi .m awalnya merupakan singkatan dari "messages" saat Objective-C pertama kali diperkenalkan, merujuk pada fitur sentral dari Objective-C
- ↑ "Objective-C Runtime Programming Guide". Apple Inc. Diarsipkan dari versi aslinya tanggal April 4, 2014. Diakses tanggal October 21, 2013.
- ↑ "'The Smalltalk-80 Programming System' - ACM SIGGRAPH 1983 Issue 8". 21 Desember 2011. Diakses tanggal 21 April 2025 – via YouTube. Juga tersedia Diarsipkan April 24, 2025, di Wayback Machine. di 'The Open Video Project'
- ↑ "Extension Methods (C# Programming Guide)". Microsoft. October 2010. Diarsipkan dari versi aslinya tanggal July 11, 2011. Diakses tanggal July 10, 2011.
- ↑ "#import directive (C++)".
- ↑ "Using C++ With Objective-C". Mac OS X Reference Library. Diarsipkan dari asli tanggal September 5, 2010. Diakses tanggal February 12, 2025.
- ↑ "Using C++ With Objective-C". Mac OS X Reference Library. Diarsipkan dari asli tanggal September 5, 2010. Diakses tanggal February 10, 2010.
- ↑ "Clang Language Extensions — Clang 3.5 documentation". Clang.llvm.org. Diarsipkan dari versi aslinya tanggal February 24, 2014. Diakses tanggal April 16, 2014.
- ↑ "Objective-C 2.0: more clues". Lists.apple.com. August 10, 2006. Diarsipkan dari asli tanggal June 18, 2009. Diakses tanggal May 30, 2010.
- ↑ "Re: Objective-C 2.0". Lists.apple.com. Diarsipkan dari asli tanggal November 24, 2010. Diakses tanggal May 30, 2010.
- ↑ "GCC 4.6 Release Series — Changes, New Features, and Fixes : GNU Project : Free Software Foundation". Gcc.gnu.org. Diarsipkan dari versi aslinya tanggal January 5, 2018. Diakses tanggal December 24, 2017.
- ↑ "ObjC2 FAQ". GNUstep. Diakses tanggal 6 January 2020.
- ↑ "Transitioning to ARC Release Notes". Apple Inc. July 17, 2012. Diarsipkan dari versi aslinya tanggal June 9, 2012. Diakses tanggal August 26, 2012.
- ↑ Apple, Inc. (2009). "Fast Enumeration". apple.com. Diarsipkan dari versi aslinya tanggal December 17, 2009. Diakses tanggal December 31, 2009.
- ↑ Apple, Inc. (August 22, 2006). "Mac OS X Leopard – Xcode 3.0". apple.com. Diarsipkan dari asli tanggal October 24, 2007. Diakses tanggal August 22, 2006.
- ↑ "Transitioning to ARC Release Notes". iOS Developer Library. Developer.apple.com. Diarsipkan dari versi aslinya tanggal September 7, 2011. Diakses tanggal April 16, 2014.
Bacaan lebih lanjut
[sunting | sunting sumber]- Cox, Brad J. (1991). Object Oriented Programming: An Evolutionary Approach. Addison Wesley. ISBN 0-201-54834-8.
Pranala luar
[sunting | sunting sumber]- Programming with Objective-C, dari Apple (13-12-2012)
- The Objective-C Programming Language, dari Apple (11-10-2011)
- 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 (Diarsipkan 23 April 2024 di Wayback Machine.)