Saya baru saja membeli Mac dan menggunakannya terutama untuk pengembangan C # di bawah VMWare Fusion. Dengan semua aplikasi Mac yang bagus di sekitar saya, saya mulai memikirkan tentang Xcode yang bersembunyi hanya dengan sekali klik, dan mempelajari Objective-C.
Sintaks antara kedua bahasa terlihat sangat berbeda, mungkin karena Objective-C berasal dari C dan C # berasal dari Java / C ++. Tetapi sintaks yang berbeda dapat dipelajari sehingga tidak masalah.
Perhatian utama saya adalah bekerja dengan bahasa dan jika itu akan membantu menghasilkan kode yang terstruktur dengan baik, dapat dibaca dan elegan. Saya sangat menikmati fitur-fitur seperti LINQ dan var di C # dan bertanya-tanya apakah ada fitur yang setara atau lebih baik / berbeda di Objective-C.
Fitur bahasa apa yang akan saya lewatkan untuk dikembangkan dengan Objective-C? Fitur apa yang akan saya dapatkan?
Sunting: Perbandingan kerangka kerja berguna dan menarik tetapi perbandingan bahasa adalah apa yang sebenarnya ditanyakan oleh pertanyaan ini (sebagian karena kesalahan saya karena awalnya menandai .net
). Agaknya, baik Cocoa maupun .NET adalah kerangka kerja yang sangat kaya dan keduanya memiliki tujuan masing-masing, satu menargetkan Mac OS X dan Windows lainnya.
Terima kasih atas pemikiran yang matang dan sudut pandang yang cukup seimbang sejauh ini!
sumber
Jawaban:
Tidak ada bahasa yang sempurna untuk semua tugas, dan Objective-C tidak terkecuali, tetapi ada beberapa hal yang sangat spesifik. Seperti menggunakan
LINQ
danvar
(yang tidak saya ketahui penggantinya secara langsung), beberapa di antaranya sangat terkait dengan bahasa, dan yang lainnya terkait dengan kerangka kerja.( CATATAN: Sama seperti C # yang digabungkan erat dengan .NET, Objective-C terkait erat dengan Cocoa. Oleh karena itu, beberapa poin saya mungkin tampak tidak terkait dengan Objective-C, tetapi Objective-C tanpa Cocoa mirip dengan C # tanpa .NET / WPF / LINQ, berjalan di bawah Mono, dll. Hanya saja, ini bukan cara yang biasa dilakukan.)
Saya tidak akan berpura-pura menguraikan sepenuhnya perbedaan, pro, dan kontra, tetapi berikut adalah beberapa yang terlintas dalam pikiran.
Salah satu bagian terbaik dari Objective-C adalah sifatnya yang dinamis - daripada memanggil metode, Anda mengirim pesan, yang dirutekan runtime secara dinamis. Dikombinasikan (dengan bijaksana) dengan pengetikan dinamis, ini dapat membuat banyak pola yang kuat menjadi lebih sederhana atau bahkan sepele untuk diterapkan.
Sebagai superset ketat dari C, Objective-C percaya bahwa Anda tahu apa yang Anda lakukan. Tidak seperti pendekatan bahasa yang dikelola dan / atau tidak aman seperti C # dan Java, Objective-C memungkinkan Anda melakukan apa yang Anda inginkan dan mengalami konsekuensinya. Jelas ini kadang-kadang bisa berbahaya, tetapi fakta bahwa bahasa tidak secara aktif mencegah Anda melakukan banyak hal cukup kuat. ( EDIT: Saya harus menjelaskan bahwa C # juga memiliki fitur dan fungsi yang "tidak aman", tetapi perilaku defaultnya adalah kode yang dikelola, yang harus Anda sisihkan secara eksplisit. Sebagai perbandingan, Java hanya mengizinkan kode yang aman untuk mengetik, dan tidak pernah memperlihatkan petunjuk mentah di seperti yang dilakukan C dan lainnya.)
Kategori (menambahkan / memodifikasi metode pada kelas tanpa subclass atau memiliki akses ke sumber) adalah pedang bermata dua yang mengagumkan. Ini dapat sangat menyederhanakan hierarki pewarisan dan menghilangkan kode, tetapi jika Anda melakukan sesuatu yang aneh, hasilnya terkadang membingungkan.
Cocoa membuat pembuatan aplikasi GUI jauh lebih sederhana dalam banyak hal, tetapi Anda harus memahami paradigma tersebut. Desain MVC tersebar luas di Cocoa, dan pola seperti delegasi, notifikasi, dan aplikasi GUI multi-utas sangat cocok untuk Objective-C.
Pengikatan kakao dan pengamatan nilai kunci dapat menghilangkan banyak kode perekat, dan kerangka kerja Kakao memanfaatkannya secara ekstensif. Pengiriman dinamis Objective-C bekerja bahu-membahu dengan ini, jadi jenis objek tidak menjadi masalah asalkan sesuai dengan nilai kuncinya.
Anda kemungkinan besar akan merindukan obat generik dan namespace, dan keduanya memiliki manfaatnya, tetapi dalam pola pikir dan paradigma Objective-C, keduanya lebih baik daripada kebutuhan. (Generik adalah tentang keamanan tipe dan menghindari casting, tetapi pengetikan dinamis di Objective-C membuat ini pada dasarnya bukan masalah. Namespaces akan bagus jika dilakukan dengan baik, tetapi cukup sederhana untuk menghindari konflik yang biayanya bisa dibilang lebih besar daripada manfaatnya, terutama untuk kode lama.)
Untuk konkurensi, Blok (fitur bahasa baru di Snow Leopard, dan diterapkan di sejumlah API Kakao) sangat berguna. Beberapa baris (sering digabungkan dengan Grand Central Dispatch, yang merupakan bagian dari libsystem pada 10.6) dapat menghilangkan boilerplate signifikan dari fungsi callback, konteks, dll. (Blok juga dapat digunakan dalam C dan C ++, dan tentunya dapat ditambahkan ke C #, yang akan luar biasa.) NSOperationQueue juga merupakan cara yang sangat nyaman untuk menambahkan konkurensi ke kode Anda sendiri, dengan mengirimkan subkelas NSOperation kustom atau blok anonim yang secara otomatis dijalankan oleh GCD pada satu atau beberapa utas berbeda untuk Anda.
sumber
alloca
,. Itu tidak membuatnya mudah diakses - Anda harus ikut serta secara eksplisit.Saya telah memprogram dalam C, C ++ dan C # sekarang selama lebih dari 20 tahun, pertama kali dimulai pada tahun 1990. Saya baru saja memutuskan untuk melihat perkembangan iPhone dan Xcode dan Objective-C. Ya ampun ... semua keluhan tentang Microsoft saya ambil kembali, saya sekarang menyadari betapa buruknya kode hal itu. Objective-C terlalu kompleks dibandingkan dengan apa yang dilakukan C #. Saya telah dimanjakan dengan C # dan sekarang saya menghargai semua kerja keras yang telah dilakukan Microsoft. Hanya membaca Objective-C dengan metode pemanggilan sulit untuk dibaca. C # elegan dalam hal ini. Itu hanya pendapat saya, saya berharap bahasa pengembangan Apple sebagus produk Apple, tetapi saya, mereka harus banyak belajar dari Microsoft. Tidak ada pertanyaan C #. Aplikasi NET. Saya bisa mendapatkan aplikasi dan berjalan berkali-kali lebih cepat daripada XCode Objective-C. Apple tentunya harus mengambil bagian dari buku Microsoft di sini dan kemudian kita akan memiliki lingkungan yang sempurna. :-)
sumber
"Just reading Objective-C with method invokes is difficult to read"
- di sini adalah hanya salah satu yang sangat subjektif argumen bahwa disebutkan di sini sebagai kontra dari obj-C. Semua lainnya hanyalah retorika yang bisa diperdebatkan.Tidak ada tinjauan teknis di sini, tapi saya hanya merasa Objective-C kurang bisa dibaca. Diberikan contoh yang diberikan Cinder6:
C #
List<string> strings = new List<string>(); strings.Add("xyzzy"); // takes only strings strings.Add(15); // compiler error string x = strings[0]; // guaranteed to be a string strings.RemoveAt(0); // or non-existant (yielding an exception)
Objective-C
NSMutableArray *strings = [NSMutableArray array]; [strings addObject:@"xyzzy"]; [strings addObject:@15]; NSString *x = strings[0]; [strings removeObjectAtIndex:0];
Ini terlihat buruk. Saya bahkan mencoba membaca 2 buku tentang itu, mereka kehilangan saya sejak awal, dan biasanya saya tidak mendapatkannya dengan buku / bahasa pemrograman.
Saya senang kami memiliki Mono untuk Mac OS, karena jika saya harus bergantung pada Apple untuk memberi saya lingkungan pengembangan yang baik ...
sumber
[NSMutableArray array]
(memori bocor) dan baris ke-4 harus dimulai denganNSString* x
atauid x
(kesalahan kompilasi) ... Ya, Objective-C tidak memiliki obat generik (sejujurnya saya tidak melewatkannya), Anda tidak objek indeks dengan sintaks array, dan API umumnya lebih verbose. To-may-to, to-mah-to. Itu benar-benar tergantung pada apa yang ingin Anda lihat. (Anda dapat menulis kode yang sama di C ++ STL dan menurut saya itu mengerikan.) Bagi saya, kode yang dapat dibaca sering kali berarti teks dari kode tersebut memberitahu Anda apa yang dilakukannya, dan dengan demikian kode Objective-C lebih disukai.List<T>.Remove
mengambil string sebagai argumen, dan menghapus kemunculan pertama dari string itu. Untuk menghapus menurut indeks, Anda perluRemoveAt
.removeObjectAtIndex:
, meski lebih bertele-tele, juga tidak ambigu tentang apa yang dilakukannya.strings[0]
danstrings.RemoveAt(0)
mengurangi kejelasan, setidaknya bagi saya. (Juga, itu selalu mengganggu saya ketika nama metode dimulai dengan huruf kapital ... Saya tahu itu adalah hal kecil, tapi itu hanya aneh.)Manajemen memori manual adalah sesuatu yang pemula dalam Objective-C tampaknya memiliki masalah paling besar, sebagian besar karena mereka pikir itu lebih kompleks daripada yang sebenarnya.
Objective-C dan Cocoa dengan ekstensi bergantung pada konvensi daripada penegakan; mengetahui dan mengikuti seperangkat aturan yang sangat kecil dan Anda mendapatkan banyak secara gratis dengan menjalankan-waktu dinamis sebagai imbalan.
Aturan yang tidak 100% benar, tetapi cukup baik untuk sehari-hari adalah:
alloc
harus dicocokkan denganrelease
di akhir lingkup saat ini.alloc
maka itu harus dikembalikan olehreturn [value autorelease];
alih-alih dicocokkan denganrelease
.Penjelasan yang lebih panjang mengikuti.
Manajemen memori didasarkan pada kepemilikan; hanya pemilik contoh objek yang boleh melepaskan objek, orang lain harus selalu tidak melakukan apa pun. Ini berarti bahwa 95% dari semua kode Anda memperlakukan Objective-C seolah-olah itu sampah yang dikumpulkan.
Lalu bagaimana dengan 5% lainnya? Anda memiliki tiga metode untuk diperhatikan, setiap instance objek yang diterima dari metode ini dimiliki oleh lingkup metode saat ini :
alloc
new
ataunewService
.copy
danmutableCopy
.Metode ini memiliki tiga opsi yang mungkin tentang apa yang harus dilakukan dengan instance objek yang dimilikinya sebelum keluar:
release
jika tidak diperlukan lagi.autorelease
.Jadi, kapan Anda harus secara proaktif mengambil alih kepemilikan dengan menelepon
retain
? Dua kasus:sumber
Tentu, jika semua yang Anda lihat dalam hidup Anda adalah Tujuan C, maka sintaksnya tampak seperti satu-satunya yang mungkin. Kami bisa menyebut Anda "perawan pemrograman".
Tetapi karena banyak kode ditulis dalam C, C ++, Java, JavaScript, Pascal, dan bahasa lain, Anda akan melihat bahwa ObjectiveC berbeda dari semuanya, tetapi tidak dengan cara yang baik. Apakah mereka punya alasan untuk ini? Mari kita lihat bahasa populer lainnya:
C ++ menambahkan banyak tambahan ke C, tetapi itu mengubah sintaks asli hanya sebanyak yang diperlukan.
C # menambahkan banyak tambahan dibandingkan dengan C ++ tetapi hanya mengubah hal-hal yang jelek di C ++ (seperti menghapus "::" dari antarmuka).
Java mengubah banyak hal, tetapi tetap menggunakan sintaks yang familier kecuali di bagian yang memerlukan perubahan.
JavaScript adalah bahasa yang benar-benar dinamis yang dapat melakukan banyak hal yang tidak bisa dilakukan ObjectiveC. Namun, penciptanya tidak menemukan cara baru untuk memanggil metode dan mengirimkan parameter hanya agar berbeda dari negara lain.
Visual Basic dapat melewatkan parameter yang rusak, seperti ObjectiveC. Anda dapat memberi nama parameter, tetapi Anda juga dapat meneruskannya dengan cara biasa. Apa pun yang Anda gunakan, itu adalah cara normal yang dipisahkan koma yang dipahami semua orang. Koma merupakan pembatas biasa, tidak hanya dalam bahasa pemrograman, tetapi di buku, koran, dan bahasa tertulis pada umumnya.
Object Pascal memiliki sintaks yang berbeda dari C, tetapi sintaksnya sebenarnya LEBIH MUDAH dibaca oleh programmer (mungkin bukan ke komputer, tapi siapa yang peduli apa yang dipikirkan komputer). Jadi mungkin mereka menyimpang, tapi setidaknya hasilnya lebih baik.
Python memiliki sintaks yang berbeda, yang bahkan lebih mudah dibaca (untuk manusia) daripada Pascal. Jadi ketika mereka mengubahnya, membuatnya berbeda, setidaknya mereka membuatnya lebih baik untuk kita para programmer.
Dan kemudian kami memiliki ObjectiveC. Menambahkan beberapa perbaikan pada C, tetapi menciptakan sintaks antarmukanya sendiri, pemanggilan metode, pengoperan parameter dan apa yang tidak. Saya bertanya-tanya mengapa mereka tidak menukar + dan - sehingga plus mengurangi dua angka. Akan lebih keren.
Steve Jobs gagal dengan mendukung ObjectiveC. Tentu saja dia tidak dapat mendukung C #, yang lebih baik, tetapi milik pesaing terburuknya. Jadi ini keputusan politik, bukan keputusan praktis. Teknologi selalu menderita ketika keputusan teknologi dibuat karena alasan politik. Dia harus memimpin perusahaan, yang dia lakukan dengan baik, dan menyerahkan masalah pemrograman kepada ahlinya.
Saya yakin akan ada lebih banyak aplikasi untuk iPhone jika dia memutuskan untuk menulis iOS dan mendukung perpustakaan dalam bahasa lain selain ObjectiveC. Bagi semua orang kecuali penggemar berat, programmer perawan, dan Steve Jobs, ObjectiveC terlihat konyol, jelek, dan menjijikkan.
sumber
NSArray
dan itu menangani pemilihan algoritma terbaik berdasarkan mesin dan sifat datanya.Satu hal yang saya suka tentang objektif-c adalah bahwa sistem objek didasarkan pada pesan, ini memungkinkan Anda melakukan hal-hal baik yang tidak dapat Anda lakukan di C # (setidaknya tidak sampai mereka mendukung kata kunci dinamis!).
Hal hebat lainnya tentang menulis aplikasi kakao adalah Interface Builder, jauh lebih bagus daripada desainer formulir di Visual Studio.
Hal-hal tentang obj-c yang mengganggu saya (sebagai pengembang C #) adalah kenyataan bahwa Anda harus mengelola memori Anda sendiri (ada pengumpulan sampah, tetapi itu tidak berfungsi di iPhone) dan itu bisa sangat bertele-tele karena sintaks pemilih dan semua [].
sumber
dynamic
hanya akan membuat Anda setengah jalan - mengimplementasikan objek dinamis sejati, bahkan dengan hal-hal sepele seperti pendelegasian pesan, membosankan bahkan dalam C # 4.0. Di sisi lain, harga untuk fleksibilitas pesan dinamis sejati melalui ObjC adalah kehilangan keamanan tipe.System.Reflection
dikombinasikan dengan ekstensi di C # 3.0, Anda dapat memanggil metode apa pun yang Anda temukan, tetapi bukan pesan yang benar, itu akan terlihat sepertiobj.PassMessage("function_name", params object[] args);
pesan yang lebih baik yang diintegrasikan ke dalam bahasa, metode yang tidak dapat dipanggil pada objek normal adalah dibutuhkan.Sebagai seorang programmer yang baru saja memulai Objective-C untuk iPhone, berasal dari C # 4.0, saya kehilangan ekspresi lambda, dan khususnya, Linq-to-XML. Ekspresi lambda adalah C # -specific, sedangkan Linq-to-XML lebih merupakan kontras .NET vs. Cocoa. Dalam aplikasi contoh yang saya tulis, saya memiliki beberapa XML dalam sebuah string. Saya ingin mengurai elemen XML itu ke dalam kumpulan objek.
Untuk mencapai ini di Objective-C / Cocoa, saya harus menggunakan kelas NSXmlParser . Kelas ini bergantung pada objek lain yang mengimplementasikan protokol NSXMLParserDelegate dengan metode yang dipanggil (baca: pesan terkirim) saat tag terbuka elemen dibaca, saat beberapa data dibaca (biasanya di dalam elemen), dan saat beberapa tag akhir elemen dibaca . Anda harus melacak status dan status penguraian. Dan sejujurnya saya tidak tahu apa yang terjadi jika XML tidak valid. Sangat bagus untuk mendapatkan detail dan mengoptimalkan kinerja, tapi oh man, itu banyak sekali kode.
Sebaliknya, inilah kode di C #:
using System.Linq.Xml; XDocument doc = XDocument.Load(xmlString); IEnumerable<MyCustomObject> objects = doc.Descendants().Select( d => new MyCustomObject{ Name = d.Value});
Dan itu saja, Anda punya koleksi objek khusus yang diambil dari XML. Jika Anda ingin memfilter elemen tersebut berdasarkan nilai, atau hanya elemen yang berisi atribut tertentu, atau jika Anda hanya menginginkan 5 elemen pertama, atau melewati 1 pertama dan mendapatkan 3 berikutnya, atau hanya mencari tahu apakah ada elemen yang dikembalikan ... BAM, semua ada di baris kode yang sama.
Ada banyak kelas sumber terbuka yang membuat pemrosesan ini jauh lebih mudah di Objective-C, sehingga melakukan banyak pekerjaan berat. Hanya saja bukan ini bawaannya.
* CATATAN: Saya tidak benar-benar mengkompilasi kode di atas, itu hanya dimaksudkan sebagai contoh untuk menggambarkan kurangnya verbositas relatif yang dibutuhkan oleh C #.
sumber
Mungkin perbedaan yang paling penting adalah manajemen memori. Dengan C # Anda mendapatkan pengumpulan sampah, berdasarkan itu menjadi bahasa berbasis CLR. Dengan Objective-C Anda perlu mengelola memori sendiri.
Jika Anda berasal dari latar belakang C # (atau bahasa modern lainnya), pindah ke bahasa tanpa manajemen memori otomatis akan sangat menyakitkan, karena Anda akan menghabiskan banyak waktu pengkodean untuk mengelola memori dengan benar (dan men-debug sebagai baik).
sumber
Berikut artikel yang cukup bagus yang membandingkan kedua bahasa tersebut: http://www.coderetard.com/2008/03/16/c-vs-objective-c/
sumber
Selain perbedaan paradigma antara kedua bahasa tersebut, tidak banyak perbedaannya. Meskipun saya benci mengatakannya, Anda dapat melakukan hal yang sama (mungkin tidak semudah) dengan .NET dan C # seperti yang Anda bisa dengan Objective-C dan Cocoa. Pada Leopard, Objective-C 2.0 memiliki pengumpulan sampah, jadi Anda tidak perlu mengelola memori sendiri kecuali Anda ingin (kompatibilitas kode dengan aplikasi Mac dan iPhone yang lebih lama adalah 2 alasan untuk menginginkannya).
Sejauh menyangkut terstruktur, kode yang dapat dibaca, banyak beban yang ada pada programmer, seperti halnya dengan bahasa lain. Namun, saya menemukan bahwa pesan yang melewati paradigma cocok untuk kode yang dapat dibaca asalkan Anda memberi nama fungsi / metode Anda dengan tepat (sekali lagi, sama seperti bahasa lain).
Saya akan menjadi orang pertama yang mengakui bahwa saya tidak terlalu familiar dengan C # atau .NET. Tetapi alasan Quinn yang tercantum di atas adalah beberapa alasan mengapa saya tidak peduli untuk menjadi seperti itu.
sumber
Panggilan metode yang digunakan dalam obj-c membuat kode mudah dibaca, menurut pendapat saya jauh lebih elegan daripada c # dan obj-c dibangun di atas c sehingga semua kode c harus berfungsi dengan baik di obj-c. Penjual besar bagi saya adalah bahwa obj-c adalah standar terbuka sehingga Anda dapat menemukan kompiler untuk sistem apa pun.
sumber