Как Objective-C сравнить с С#?

Недавно я приобрел Mac и использовал его в основном для разработки С# под VMWare Fusion. Со всеми замечательными приложениями Mac вокруг меня я начал думать о том, что Xcode скрывается только на установочном клике и изучает Objective-C.

Синтаксис между двумя языками выглядит очень по-разному, по-видимому, потому что Objective-C имеет свое происхождение в C и С#, его происхождение происходит в Java/С++. Но различные синтаксисы можно узнать, так что это должно быть хорошо.

Моя основная забота - работать с языком, и если это поможет создать хорошо структурированный, читаемый и элегантный код. Мне действительно нравятся такие функции, как LINQ и var на С#, и интересно, есть ли в Objective-C эквиваленты или лучше/разные функции.

Какие языковые возможности мне не хватает разработки с помощью Objective-C? Какие функции я получу?

Изменить:. Рациональные сравнения полезны и интересны, но сравнение языков - это то, что действительно задает этот вопрос (частично моя ошибка для первоначальной маркировки с помощью .net). Предположительно, как Cocoa, так и .NET - очень богатые фреймворки сами по себе, и оба имеют свою цель, один предназначен для Mac OS X и других Windows.

Спасибо за хорошо продуманные и разумно сбалансированные точки зрения до сих пор!

Ответ 1

Язык не идеален для всех задач, а Objective-C не является исключением, но есть некоторые специфические тонкости. Подобно использованию LINQ и var (для которых я не знаю о прямой замене), некоторые из них строго связаны с языком, а другие связаны с каркасом.

( ПРИМЕЧАНИЕ: Точно так же, как С# тесно связан с .NET, Objective-C тесно связан с Cocoa. Следовательно, некоторые из моих точек могут казаться не связанными с Objective-C, но Objective-C без Cocoa сродни С# без .NET/WPF/LINQ, работает под Mono и т.д. Это просто не так, как обычно делаются.)

Я не буду претендовать на то, чтобы полностью разобраться в различиях, плюсах и минусах, но вот некоторые из них приходят в голову.

  • Одна из лучших частей Objective-C - это динамическая природа, а не вызывающие методы, вы отправляете сообщения, которые динамические маршруты запускаются динамически. Комбинированный (разумно) с динамической типизацией, это может сделать множество мощных шаблонов более простым или даже тривиальным для реализации.

  • Как строгий надмножество C, Objective-C доверяет, что вы знаете, что делаете. В отличие от управляемого и/или типичного подхода к таким языкам, как С# и Java, Objective-C позволяет вам делать то, что вы хотите, и испытывать последствия. Очевидно, что это может быть опасно время от времени, но тот факт, что язык не мешает вам делать большинство вещей, достаточно эффективен. ( EDIT: Я должен уточнить, что С# также имеет "небезопасные" функции и функциональные возможности, но по умолчанию они управляются кодом, который вы должны явно отказаться. Для сравнения, Java только позволяет использовать код типов и никогда не выводит raw-указатели так, как это делают C и другие.)

  • Категории (добавление/модификация методов в классе без подкласса или доступ к источнику) - это удивительный обоюдоострый меч. Он может значительно упростить иерархии наследования и исключить код, но если вы делаете что-то странное, результаты могут иногда озадачиваться.

  • Cocoa значительно упрощает создание приложений с графическим интерфейсом, но вам нужно обернуть вокруг парадигмы. Дизайн MVC широко распространен в Cocoa, а шаблоны, такие как делегаты, уведомления и многопоточные приложения с графическим интерфейсом, хорошо подходят для Objective-C.

  • Cocoa привязки и наблюдение за ключевыми значениями могут устранить тонны кода клея, а фреймворки Cocoa используют это широко. Objective-C динамическая рассылка работает рука об руку с этим, поэтому тип объекта не имеет значения до тех пор, пока он совместим с ключом.

  • Скорее всего, вы пропустите роды и пространства имен, и у них есть свои преимущества, но в мышлении и парадигме Objective-C они будут скорее тонкостями, чем потребностями. (Generics - все о безопасности типов и избегании кастинга, но динамическая типизация в Objective-C делает это по существу не проблемой. Пространства имен были бы хороши, если бы все было хорошо, но это достаточно просто, чтобы избежать конфликтов, которые, возможно, перевешивают преимущества, особенно для устаревшего кода.)

  • Для concurrency Блоки (новая языковая функция в Snow Leopard и реализована во множестве API-интерфейсов Cocoa) чрезвычайно полезны. Несколько строк (часто в сочетании с Grand Central Dispatch, которая является частью libsystem на 10.6), могут устранить значительный шаблон функций обратного вызова, контекста и т.д. (Блоки также могут использоваться на C и С++ и могут быть добавлены к С# что было бы замечательно.) NSOperationQueue также очень удобный способ добавить concurrency в свой собственный код, отправив либо пользовательские подклассы NSOperation, либо анонимные блоки, которые GCD автоматически выполняет для одного или нескольких разных потоков для вас.

    /li >

Ответ 2

Я программировал на C, С++ и С# уже более 20 лет, сначала начал работать в 1990 году. Я только что решил посмотреть разработки iPhone и Xcode и Objective-C. О, боже мой... все жалобы на Microsoft, которые я забираю, теперь понимаю, как плохой код был. Objective-C по сравнению с тем, что делает С#. Я был испорчен С#, и теперь я ценю всю тяжелую работу, которую Microsoft вложила. Простое чтение Objective-C с помощью методов вызывает трудность для чтения. С# является элегантным в этом. Это только мое мнение, я надеялся, что язык разработки Apple был хорош как продукты Apple, но, дорогая, им есть чему поучиться у Microsoft. Нет никаких проблем с С#.NET-приложением. Я могу получить приложение быстрее и быстрее, чем XCode Objective-C. Apple, безусловно, должна взять лист из книги Microsoft здесь, а затем у нас будет идеальная среда.: -)

Ответ 3

Нет технического обзора здесь, но я просто нахожу Objective-C гораздо менее удобочитаемым. Учитывая пример, Cinder6 дал вам:

С#

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];

Это выглядит ужасно. Я даже пробовал читать 2 книги, они рано потеряли меня, и обычно я не получаю это с помощью книг/языков программирования.

Я рад, что у нас есть Mono для Mac OS, потому что, если бы мне пришлось полагаться на Apple чтобы дать мне хорошую среду разработки...

Ответ 4

У ручного управления памятью есть что-то новички до Objective-C, похоже, имеют большую проблему, главным образом потому, что они считают, что это сложнее, чем есть.

Objective-C и Cocoa по расширению полагается на соглашения по принудительному исполнению; знайте и следуйте очень малым наборам правил, и вы получаете много свободного от динамического времени выполнения взамен.

Правило не 100% истинное, но достаточно хорошее для каждодневного:

  • Каждый вызов alloc должен совпадать с release в конце текущей области.
  • Если возвращаемое значение для вашего метода было получено с помощью alloc, то оно должно быть возвращено return [value autorelease]; вместо соответствия release.
  • Использовать свойства, и нет правила три.

Далее следует более подробное объяснение.

Управление памятью основано на собственности; только владелец экземпляра объекта должен когда-либо выпускать объект, каждый else всегда должен ничего не делать. Это означает, что в 95% всего кода вы обрабатываете Objective-C, как если бы он собирался с мусором.

А как насчет остальных 5%? У вас есть три метода для поиска, любой экземпляр объекта, полученный от этого метода, принадлежит текущей области метода:

  • alloc
  • Любой метод, начинающийся со слова new, например new или newService.
  • Любой метод, содержащий слово copy, например copy и mutableCopy.

У метода есть три возможных варианта того, что делать с принадлежащими ему экземплярами объектов до его выхода:

  • Отпустите его, используя release, если он больше не нужен.
  • Предоставить право собственности на поле a (переменная экземпляра) или глобальную переменную, просто назначив ее.
  • Откажитесь от владения, но дайте кому-то возможность взять собственность до того, как экземпляр уйдет, вызвав autorelease.

Итак, когда вы должны активно принимать участие, вызывая retain? Два случая:

  • При назначении полей в ваших инициализаторах.
  • При ручном внедрении метода setter.

Ответ 5

Конечно, если все, что вы видели в своей жизни, это Objective C, то его синтаксис выглядит как единственно возможным. Мы могли бы назвать вас "программирующей девственницей".

Но так как много кода написано на языках C, С++, Java, JavaScript, Pascal и других языках, вы увидите, что ObjectiveC отличается от всех из них, но не в хорошем смысле. У них есть причина для этого? Давайте посмотрим другие популярные языки:

С++ добавил много дополнительных возможностей для C, но он изменил исходный синтаксис только столько, сколько необходимо.

С# добавила много дополнений по сравнению с С++, но изменила только то, что было уродливым на С++ (например, удаление "::" из интерфейса).

Java изменила много вещей, но сохранила привычный синтаксис, кроме тех частей, где это изменение было необходимо.

JavaScript - это полностью динамический язык, который может делать много вещей, которые ObjectiveC не может. Тем не менее, его создатели не изобретали новый способ вызова методов и передачи параметров, чтобы отличаться от остального мира.

Visual Basic может передавать параметры не в порядке, как ObjectiveC. Вы можете назвать параметры, но вы также можете передать их обычным способом. Независимо от того, что вы используете, это обычный способ с разделителями-запятыми, который каждый понимает. Comma - обычный разделитель не только на языках программирования, но и в книгах, газетах и ​​на письменном языке вообще.

Объект Pascal имеет другой синтаксис, чем C, но его синтаксис на самом деле EASIER читается для программиста (возможно, не для компьютера, но кто заботится о том, что думает компьютер). Так что, возможно, они отступили, но по крайней мере их результат лучше.

Python имеет другой синтаксис, который еще проще читать (для людей), чем Pascal. Поэтому, когда они меняли его, делая его другим, по крайней мере, они помогли нам программистам.

И тогда у нас есть ObjectiveC. Добавляем некоторые улучшения в C, но придумывая свой собственный синтаксис интерфейса, вызов метода, передачу параметров, а что нет. Интересно, почему они не поменялись + и - так что плюс вычитает два числа. Было бы еще холоднее.

Стив Джобс напортачил, поддерживая ObjectiveC. Конечно, он не может поддерживать С#, что лучше, но принадлежит его худшему конкуренту. Так что это политическое решение, а не практическое. Технология всегда страдает, когда технические решения принимаются по политическим соображениям. Он должен возглавить компанию, что он делает добро, и оставить вопросы программирования реальным экспертам.

Я уверен, что для iPhone будет еще больше приложений, если он решит написать iOS и библиотеки поддержки на любом другом языке, кроме ObjectiveC. Для всех, кроме умелых фанатов, девственных программистов и Стива Джобса, ObjectiveC выглядит смешно, уродливо и отталкивает.

Ответ 6

Одна вещь, которая мне нравится в objective-c, заключается в том, что объектная система основана на сообщениях, она позволяет делать действительно приятные вещи, которые вы не могли бы сделать на С# (по крайней мере, пока они не поддерживают ключевое слово dynamic!).

Еще одна важная вещь в написании приложений cocoa - это интерфейс Builder, это намного лучше, чем конструктор форм в Visual Studio.

Что касается obj-c, который меня раздражает (как разработчик С#), это тот факт, что вам нужно управлять собственной памятью (там сборка мусора, но это не работает на iPhone) и что это может быть очень многословный из-за синтаксиса селектора и всех [].

Ответ 7

Как программист, начинающий с Objective-C для iPhone, начиная с С# 4.0, мне не хватает лямбда-выражений и, в частности, Linq-to-XML. Лямбда-выражения являются С# -специфичными, в то время как Linq-to-XML действительно больше отличается от .NET и Cocoa. В примере приложения, которое я писал, у меня был некоторый XML в строке. Я хотел разобрать элементы этого XML в коллекцию объектов.

Чтобы выполнить это в Objective-C/Cocoa, мне пришлось использовать класс NSXmlParser. Этот класс полагается на другой объект, который реализует протокол NSXMLParserDelegate с методами, которые вызывают (чтение: отправленные сообщения), когда тег открытого элемента read, когда некоторые данные считываются (как правило, внутри элемента), и когда считывается некоторый конечный тег элемента. Вы должны отслеживать состояние синтаксического разбора и состояние. И я честно понятия не имею, что произойдет, если XML недействителен. Это отлично подходит для того, чтобы перейти к деталям и оптимизировать производительность, но о человеке, что много кода.

В отличие от этого здесь код в С#:

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 или просто выяснить, были ли какие-либо элементы возвращены... BAM, все в одной строке кода.

Существует много классов с открытым исходным кодом, которые значительно облегчают эту обработку в Objective-C, что делает большую часть тяжелого подъема. Это просто не встроено.

* ПРИМЕЧАНИЕ. Я на самом деле не компилировал вышеприведенный код, это просто означает пример, иллюстрирующий относительное отсутствие подробностей, требуемых С#.

Ответ 8

Наверное, самым важным отличием является управление памятью. С С# вы получаете сбор мусора, благодаря тому, что это язык CLR. С помощью Objective-C вам нужно самому управлять памятью.

Если вы работаете на фоне С# (или на любом современном языке), переход на язык без автоматического управления памятью будет очень болезненным, так как вы потратите много времени на правильное управление памятью ( и отладки).

Ответ 10

Вызов метода, используемый в obj-c make для легко читаемого кода, по моему мнению, намного более изящный, чем С#, и obj-c построен поверх c, поэтому весь c-код должен работать нормально в obj-c. Крупным продавцом для меня является то, что obj-c является открытым стандартом, поэтому вы можете найти компиляторы для любой системы.

Ответ 11

Помимо различий в парадигме между двумя языками, нет большой разницы. Насколько я ненавижу это говорить, вы можете делать то же самое (возможно, не так легко) с .NET и С#, как вы можете с Objective-C и Cocoa. Начиная с Leopard, Objective-C 2.0 имеет сбор мусора, поэтому вам не нужно самостоятельно управлять памятью, если вы не хотите (совместимость кода со старыми Mac и iPhone-приложениями - это 2 причины).

Что касается структурированного, читаемого кода, то большая часть бремени лежит на программисте, как и на любом другом языке. Тем не менее, я нахожу, что парадигма передачи сообщений хорошо читается для читаемого кода, если вы называете свои функции/методы соответствующим образом (опять же, как и любой другой язык).

Я буду первым, кто признает, что я не очень хорошо знаком с С# или .NET. Но причины, о которых говорилось выше, - это немало причин, по которым я не хочу этого делать.