Недавно я купил Mac и использую его в основном для разработки на C # под VMWare Fusion. Со всеми хорошими приложениями для Mac я начал думать о Xcode, скрывающемся всего в одном клике по установке и изучении Objective-C.
Синтаксис между двумя языками выглядит очень разным, предположительно потому, что Objective-C берет свое начало в C, а C # - в Java / C ++. Но можно изучить разные синтаксисы, так что все должно быть в порядке.
Меня больше всего беспокоит работа с языком, и поможет ли он создать хорошо структурированный, читаемый и элегантный код. Мне очень нравятся такие функции, как LINQ и var в C #, и мне интересно, есть ли в Objective-C эквиваленты или лучшие / разные функции.
Какие языковые функции я буду скучать при разработке с Objective-C? Какие функции я получу?
Изменить: сравнения фреймворков полезны и интересны, но сравнение языков - это то, что на самом деле задает этот вопрос (отчасти моя вина за исходную маркировку .net
). Предположительно, как Cocoa, так и .NET являются очень богатыми фреймворками сами по себе, и у обоих есть свои цели: одна нацелена на Mac OS X, а другая - на Windows.
Спасибо за хорошо продуманные и разумно сбалансированные точки зрения!
источник
Ответы:
Ни один язык не подходит для всех задач, и Objective-C не исключение, но есть некоторые очень специфические тонкости. Как и использование
LINQ
иvar
(для которого я не знаю прямой замены), некоторые из них строго связаны с языком, а другие - с фреймворком.( ПРИМЕЧАНИЕ: так же, как C # тесно связан с .NET, Objective-C тесно связан с Cocoa. Следовательно, некоторые из моих соображений могут показаться не связанными с Objective-C, но Objective-C без Cocoa сродни C # без .NET / WPF / LINQ, работающий под Mono и т. Д. Это просто не так, как обычно.)
Я не буду претендовать на то, чтобы подробно описывать различия, плюсы и минусы, но вот некоторые, которые приходят на ум.
Одна из лучших частей Objective-C - это динамический характер: вместо вызова методов вы отправляете сообщения, которые среда выполнения динамически направляет. В сочетании (разумно) с динамической типизацией это может упростить или даже тривиально реализовать множество мощных шаблонов.
Как строгий надмножество C, Objective-C полагается, что вы знаете, что делаете. В отличие от управляемого и / или типизированного подхода таких языков, как C # и Java, Objective-C позволяет вам делать то, что вы хотите, и испытывать последствия. Очевидно, что временами это может быть опасно, но тот факт, что язык активно не мешает вам делать большинство вещей, довольно мощный. ( РЕДАКТИРОВАТЬ: я должен уточнить, что C # также имеет «небезопасные» функции и возможности, но их поведение по умолчанию - это управляемый код, от которого вы должны явно отказаться. Для сравнения, Java допускает только типизированный код и никогда не предоставляет необработанные указатели в так, как это делают C и другие.)
Категории (добавление / изменение методов в классе без создания подклассов или без доступа к исходному тексту) - это отличный палка о двух концах. Это может значительно упростить иерархию наследования и исключить код, но если вы сделаете что-то странное, результаты иногда могут быть непонятными.
Какао значительно упрощает создание приложений с графическим интерфейсом пользователя во многих отношениях, но вам действительно нужно хорошо разбираться в парадигме. Дизайн MVC широко распространен в Какао, а такие шаблоны, как делегаты, уведомления и многопоточные приложения с графическим интерфейсом, хорошо подходят для Objective-C.
Связывание какао и наблюдение за ключом могут устранить тонны связующего кода, и фреймворки какао широко это используют. Динамическая отправка Objective-C работает рука об руку с этим, поэтому тип объекта не имеет значения, если он соответствует ключу-значению.
Скорее всего, вы пропустите универсальные шаблоны и пространства имен, и у них есть свои преимущества, но с точки зрения мышления и парадигмы Objective-C они были бы тонкостью, а не необходимостью. (Обобщения - это все о безопасности типов и предотвращении приведения типов, но динамическая типизация в Objective-C делает это по существу несложным. Пространства имен было бы неплохо, если бы все было сделано хорошо, но это достаточно просто, чтобы избежать конфликтов, стоимость которых, возможно, перевешивает преимущества, особенно для устаревшего кода.)
Для параллелизма чрезвычайно полезны блоки (новая языковая функция в Snow Leopard, реализованная во множестве API-интерфейсов Cocoa). Несколько строк (часто в сочетании с Grand Central Dispatch, который является частью libsystem в 10.6) могут устранить значительный шаблон функций обратного вызова, контекста и т. Д. (Блоки также могут использоваться в C и C ++ и, безусловно, могут быть добавлены в C #, что было бы круто.) NSOperationQueue также является очень удобным способом добавления параллелизма в ваш собственный код, отправляя либо пользовательские подклассы NSOperation, либо анонимные блоки, которые GCD автоматически выполняет за вас в одном или нескольких различных потоках.
источник
alloca
. Это просто не делает их доступными - вам нужно явно указать.Я программировал на C, C ++ и C # уже более 20 лет, впервые начал в 1990 году. Я только что решил взглянуть на разработку iPhone, Xcode и Objective-C. О, боже мой ... все жалобы на Microsoft я беру обратно, теперь я понимаю, насколько плох был код. Objective-C слишком сложен по сравнению с тем, что делает C #. Я был избалован C #, и теперь я ценю всю тяжелую работу, проделанную Microsoft. Просто читать Objective-C с вызовами методов трудно. C # в этом элегантен. Это всего лишь мое мнение, я надеялся, что язык разработки Apple будет таким же хорошим, как и продукты Apple, но, дорогой я, им есть чему поучиться у Microsoft. Нет никаких сомнений в том, что приложение C # .NET. Я могу запустить и запустить приложение во много раз быстрее, чем XCode Objective-C. Apple, безусловно, стоит взять здесь листок из книги Microsoft, и тогда у нас будет идеальная среда. :-)
источник
"Just reading Objective-C with method invokes is difficult to read"
- вот только один очень субъективный аргумент, который упоминается здесь как минусы Obj-C. Все остальное - спорная риторика.Здесь нет технического обзора, но я считаю, что Objective-C гораздо менее читабелен. Учитывая пример, который 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)
Цель-C
NSMutableArray *strings = [NSMutableArray array]; [strings addObject:@"xyzzy"]; [strings addObject:@15]; NSString *x = strings[0]; [strings removeObjectAtIndex:0];
Выглядит ужасно. Я даже пробовал читать по нему две книги, они потеряли меня рано, и обычно я не получаю этого с книгами / языками по программированию.
Я рад, что у нас есть Mono для Mac OS, потому что если бы мне пришлось положиться на Apple, чтобы дать мне хорошую среду разработки ...
источник
[NSMutableArray array]
вместо этого (утечка памяти), а 4-я строка должна начинаться сNSString* x
илиid x
(ошибка компиляции) ... Да, в Objective-C не хватает дженериков (я, честно говоря, их не скучаю), вы не делаете Объекты не индексируются с синтаксисом массива, а API обычно более подробны. To-may-to, to-mah-to. Все сводится к тому, что вы предпочитаете видеть. (Вы могли бы написать тот же код на C ++ STL, и я бы подумал, что это ужасно.) Для меня читаемый код часто означает, что текст кода говорит вам, что он делает, и поэтому код Objective-C предпочтительнее.List<T>.Remove
принимает строку в качестве аргумента и удаляет первое появление этой строки. Чтобы удалить по индексу, вам понадобитсяRemoveAt
.removeObjectAtIndex:
, хотя и более подробна, также недвусмысленно говорит о том, что она делает.strings[0]
иstrings.RemoveAt(0)
снижает ясность, по крайней мере, для меня. (Кроме того, меня всегда беспокоит, когда имена методов начинаются с заглавной буквы ... Я знаю, что это мелочь, но это просто странно.)Ручное управление памятью - это то, с чем у новичков в Objective-C, похоже, больше всего проблем, в основном потому, что они думают, что это сложнее, чем есть на самом деле.
Objective-C и Cocoa в большей степени полагаются на соглашения, а не на исполнение; знайте и следуйте очень небольшому набору правил, и вы получите много бесплатного взамен динамического времени выполнения.
Правило не на 100%, но для повседневного использования достаточно:
alloc
должен совпадать с символом arelease
в конце текущей области.alloc
времени, оно должно быть возвращено,return [value autorelease];
а не совпадать сrelease
.Далее следует более подробное объяснение.
Управление памятью основано на владении; только владелец экземпляра объекта должен когда-либо освобождать объект, все остальные всегда ничего не должны делать. Это означает, что в 95% всего кода вы относитесь к Objective-C как к сборщику мусора.
Так что насчет остальных 5%? У вас есть три метода, на которые нужно обратить внимание, любой экземпляр объекта, полученный из этого метода, принадлежит текущей области действия метода :
alloc
new
илиnewService
.copy
иmutableCopy
.У метода есть три возможных варианта того, что делать с экземплярами принадлежащих ему объектов перед выходом:
release
если он больше не нужен.autorelease
.Итак, когда вам следует активно брать на себя ответственность, позвонив
retain
? Два случая:источник
Конечно, если все, что вы видели в своей жизни, - это Objective C, то его синтаксис выглядит единственно возможным. Мы могли бы назвать вас «девственницей программирования».
Но поскольку много кода написано на C, C ++, Java, JavaScript, Pascal и других языках, вы увидите, что ObjectiveC отличается от всех них, но не в хорошем смысле. Была ли у них на это причина? Посмотрим на другие популярные языки:
C ++ добавил к C много дополнений, но изменил исходный синтаксис лишь настолько, насколько это было необходимо.
C # добавил много дополнительных функций по сравнению с C ++, но изменил только то, что было некрасиво в C ++ (например, удаление символа "::" из интерфейса).
Java изменила много вещей, но сохранила знакомый синтаксис, за исключением тех частей, где это изменение было необходимо.
JavaScript - это полностью динамический язык, который может делать многое, чего не может ObjectiveC. Тем не менее, его создатели не изобрели новый способ вызова методов и передачи параметров только для того, чтобы отличаться от остального мира.
Visual Basic может передавать параметры не по порядку, как и ObjectiveC. Вы можете назвать параметры, но вы также можете передать их обычным способом. Что бы вы ни использовали, это обычный способ, разделенный запятыми, который все понимают. Запятая является обычным разделителем не только в языках программирования, но и в книгах, газетах и письменной речи в целом.
Object Pascal имеет синтаксис, отличный от C, но его синтаксис на самом деле ЛЕГЧЕ читать для программиста (возможно, не для компьютера, но кого волнует, что думает компьютер). Так что, возможно, они отклонились, но, по крайней мере, их результат лучше.
У Python другой синтаксис, который даже легче читать (для людей), чем Паскаль. Поэтому, когда они изменили его, сделали его другим, по крайней мере, они сделали его лучше для нас, программистов.
И затем у нас есть ObjectiveC. Добавлены некоторые улучшения в C, но изобретен собственный синтаксис интерфейса, вызов методов, передача параметров и многое другое. Интересно, почему они не поменяли местами + и -, так что плюс вычитает два числа. Было бы еще круче.
Стив Джобс облажался, поддержав ObjectiveC. Конечно, он не может поддерживать C #, что лучше, но принадлежит его худшему конкуренту. Так что это политическое решение, а не практическое. Технологии всегда страдают, когда технические решения принимаются по политическим причинам. Он должен возглавить компанию, что у него хорошо получается, а вопросы программирования оставить настоящим экспертам.
Я уверен, что приложений для iPhone было бы еще больше, если бы он решил писать iOS и поддерживать библиотеки на любом другом языке, кроме ObjectiveC. Всем, кроме убежденных фанатов, девственных программистов и Стива Джобса, ObjectiveC выглядит смешно, уродливо и отталкивающе.
источник
NSArray
и он обрабатывает выбор лучшего алгоритма на основе машины и характера данных.Что мне нравится в objective-c, так это то, что объектная система основана на сообщениях, она позволяет делать действительно хорошие вещи, которые вы не могли бы сделать в C # (по крайней мере, пока они не поддерживают ключевое слово dynamic!).
Еще одна замечательная вещь в написании приложений какао - это Interface Builder, он намного лучше, чем конструктор форм в Visual Studio.
Что меня раздражает (как разработчика C #) в obj-c, так это то, что вам нужно управлять собственной памятью (есть сборка мусора, но это не работает на iPhone) и что она может быть очень многословной из-за синтаксис селектора и все [].
источник
dynamic
это поможет вам только на полпути - реализация настоящего динамического объекта, даже с такими тривиальными вещами, как делегирование сообщений, утомительна даже в C # 4.0. С другой стороны, ценой гибкости, истинной динамической передачи сообщений а-ля ObjC, является потеря безопасности типов.System.Reflection
сочетании с расширениями в C # 3.0, вы можете вызвать любой метод, который найдете, но это не настоящая передача сообщений, это будет выглядетьobj.PassMessage("function_name", params object[] args);
для лучшей передачи сообщений, интегрированной в язык, метод, который отсутствует, вызываемый для обычного объекта, будет необходимо.Как программист, только начинающий работать с Objective-C для iPhone, начиная с C # 4.0, мне не хватает лямбда-выражений и, в частности, Linq-to-XML. Лямбда-выражения специфичны для C #, тогда как Linq-to-XML на самом деле больше контрастирует между .NET и Cocoa. В примере приложения, которое я писал, у меня был XML в строке. Я хотел разобрать элементы этого XML на коллекцию объектов.
Чтобы добиться этого в Objective-C / Cocoa, мне пришлось использовать класс NSXmlParser . Этот класс опирается на другой объект, который реализует протокол NSXMLParserDelegate с методами, которые вызываются (чтение: отправленные сообщения) при чтении открытого тега элемента, при чтении некоторых данных (обычно внутри элемента) и при чтении конечного тега какого-либо элемента. . Вы должны отслеживать статус и состояние синтаксического анализа. И я, честно говоря, понятия не имею, что произойдет, если XML недействителен. Он отлично подходит для того, чтобы углубиться в детали и оптимизировать производительность, но, черт возьми, это очень много кода.
Напротив, вот код на C #:
using System.Linq.Xml; XDocument doc = XDocument.Load(xmlString); IEnumerable<MyCustomObject> objects = doc.Descendants().Select( d => new MyCustomObject{ Name = d.Value});
Вот и все, у вас есть коллекция настраиваемых объектов, взятых из XML. Если вы хотите отфильтровать эти элементы по значению или только те, которые содержат определенный атрибут, или если вам просто нужны первые 5, или пропустить первый 1 и получить следующие 3, или просто узнать, были ли возвращены какие-либо элементы ... БАМ, все в той же строчке кода.
Есть много классов с открытым исходным кодом, которые значительно упрощают эту обработку в Objective-C, так что большая часть тяжелой работы ложится на него. Это просто не встроено.
* ПРИМЕЧАНИЕ: на самом деле я не компилировал приведенный выше код, он просто предназначен для примера, чтобы проиллюстрировать относительную недостаточную многословность, требуемую C #.
источник
Наверное, самое важное отличие - это управление памятью. С C # вы получаете сборку мусора, поскольку он является языком на основе CLR. С Objective-C вам нужно самостоятельно управлять памятью.
Если вы работаете с C # (или с любого современного языка, если на то пошло), переход на язык без автоматического управления памятью будет действительно болезненным, поскольку вы потратите много времени на кодирование на правильное управление памятью (и отладку как Что ж).
источник
Вот довольно хорошая статья, в которой сравниваются два языка: http://www.coderetard.com/2008/03/16/c-vs-objective-c/
источник
Кроме разницы в парадигме между двумя языками, большой разницы нет. Как бы мне не хотелось это говорить, вы можете делать те же вещи (вероятно, не так легко) с .NET и C #, как с Objective-C и Какао. Что касается Leopard, Objective-C 2.0 имеет сборку мусора, поэтому вам не нужно самостоятельно управлять памятью, если вы этого не хотите (совместимость кода со старыми приложениями Mac и iPhone - это две причины, по которым это нужно).
Что касается структурированного, читаемого кода, большая часть бремени ложится на программиста, как и в случае с любым другим языком. Однако я считаю, что парадигма передачи сообщений хорошо поддается читаемому коду при условии, что вы соответствующим образом называете свои функции / методы (опять же, как и любой другой язык).
Я первым признаю, что не очень хорошо знаком с C # или .NET. Но перечисленные выше причины, по которым Куинн, - это довольно много причин, по которым я не хочу им становиться.
источник
Вызовы методов, используемые в obj-c, делают код легко читаемым, на мой взгляд, намного элегантнее, чем c #, а obj-c построен поверх c, поэтому весь код c должен нормально работать в obj-c. Но больше всего мне нравится то, что obj-c - это открытый стандарт, поэтому вы можете найти компиляторы для любой системы.
источник