- Яблочное сравнение: Swift vs Objective-C
- Objective-C
- Swift
- Обзор мнений и статистики
- Objective-C
- Swift
- Обзор мнений и статистики
- Objective-C id as Swift Any
- Overriding methods and conforming to protocols
- Untyped Collections
- The AnyHashable Type
- Explicit Conversion for Unbridged Contexts
- AnyObject Member Lookup
- Swift Value Types in Objective-C
- Linux Portability
- Learning More
Яблочное сравнение: Swift vs Objective-C
Objective-C
Краткое описание. Язык, созданный в начале 80-х годов прошлого века, путём скрещивания С с популярным в то время Smalltalk. Изначально воспринимался, как простая надстройка, модифицирующая некоторые синтаксические конструкции, но после того, как за лицензирование взялась сначала компания NeXT, а потом на правах преемника и Apple, Objective-C стал одним из наиболее популярных языков для разработки приложений.
Динамическая типизация. В некоторых случаях, это действительно может стать ключевым преимуществом. Например, упрощает создание несложных программ.
Документация и сообщества. Более 20 лет успешного применения языка поспособствовали появлению большого количества качественных ресурсов и книг. Сегодня любой, кто желает изучить Objective-C, без труда найдёт ответ на интересующий вопрос на просторах интернета.
В сравнении с С++, да и многими другими языками того времени, Objective-C предоставляет разработчику куда больше гибкости.
Относительная простота синтаксиса. Простота заключается в первую очередь в понимании алгоритмов и того, как работает исполняемая машина.
Низкая читаемость кода, что затрудняет изучение языка новичкам.
Динамическая типизация предполагает возможность появления (пропуска) ошибок даже во время компиляции. В частности, банальные опечатки могут серьёзно затянуть процесс.
Ограниченная функциональность. Вполне логично, что язык, созданный в прошлом столетии, не может покрыть ту функциональность, что присуща современным конкурентам.
Не самая высокая производительность, опять-таки вызванная динамической типизацией.
Swift
Краткое описание. В 2014 году специалисты Apple представили миру замену привычному Objective-C. Среди преследуемых целей были заявлены повышенная читаемость кода и устойчивость к ошибкам разработчика. Что получилось по факту, давайте посмотрим.
Для написания приложения требуется меньше кода, хотя бы просто потому, что здесь реализован упрощенный принцип работы с повторяющимися строками и заявлениями.
Удобен для чтения. Стандартное достоинство любого современного языка.
Больше возможностей по сравнению с Objective-C, в частности возможность управлять памятью.
Полноценное взаимодействие с кодом, написанным на Objective-C.
Повышенная безопасность. Это выражается и в обработке указателей, и в дотошности компилятора, и в том, что в саму компиляцию можно встроить опциональную переменную nil для обеспечения обратной связи.
Из-за молодости языка и не переведённых на Swift кодов OS X и iOS требуется хотя бы минимальное знание Objective-C;
Компилятор выдаёт излишние и просто сбивающие с толку ошибки, которые разработчику, пришедшему с других языков покажутся как минимум необычными.
Взглянув на все плюсы и минусы, превосходство Swift сомнений не вызывает. Но что говорит статистика?
Обзор мнений и статистики
GitHub, периодически публикующий статистику по созданным исходникам кода, утверждает, что на сегодня Swift уже на самой вершине.
Покопавшись на портале Quora, ярые сторонники Objective-C смогут поднять себе настроение, прочитав сколько Swift уступает по производительности другим языкам.
Большинство профессиональных разработчиков, отвечая на вопрос “какой язык учить: Swift или Objective-C?”, уверенно отвечает — оба.
Что касается мнения крупных порталов, то здесь мнение единодушно: вряд ли вы найдете хоть одну статью, где победу в сравнении одерживает Objective-C. Исключительно Swift. Именно поэтому мы приглашаем вас на интенсив по основам Swift.
Некоторые преимущества есть у языка Objective-C, да и опытные разработчики склонны идеализировать его. Но от тотального яблочного господства Swift отделяет время и кропотливая работа создателей над недостатками. Ведь, довольно логично, что язык, явившийся миру всего пару лет назад должен пройти непростую стадию народной критики и доработки, прежде чем взойти на престол. А Objective-C постепенно уйдёт в историю, оставив о себе лишь добрую память.
Язык Swift по замыслу его создателей призван не только заменить Objective-C в качестве базового для разработки приложений для iOS, но и заменить C во всех остальных сферах, в том числе IoT. Но если бы Swift был так хорош, как о нём говорят, то давно бы восседал на вершинах рейтингов. Но пока это не так. Поэтому не будем забегать вперёд и пока что постараемся ответить на основной вопрос: действительно ли Swift лучше Objective-C? Для этого рассмотрим основные плюсы и минусы.
Objective-C
Краткое описание. Язык, созданный в начале 80-х годов прошлого века, путём скрещивания С с популярным в то время Smalltalk. Изначально воспринимался, как простая надстройка, модифицирующая некоторые синтаксические конструкции, но после того, как за лицензирование взялась сначала компания NeXT, а потом на правах преемника и Apple, Objective-C стал одним из наиболее популярных языков для разработки приложений.
Динамическая типизация. В некоторых случаях, это действительно может стать ключевым преимуществом. Например, упрощает создание несложных программ.
Документация и сообщества. Более 20 лет успешного применения языка поспособствовали появлению большого количества качественных ресурсов и книг. Сегодня любой, кто желает изучить Objective-C, без труда найдёт ответ на интересующий вопрос на просторах интернета.
В сравнении с С++, да и многими другими языками того времени, Objective-C предоставляет разработчику куда больше гибкости.
Относительная простота синтаксиса. Простота заключается в первую очередь в понимании алгоритмов и того, как работает исполняемая машина.
Низкая читаемость кода, что затрудняет изучение языка новичкам.
Динамическая типизация предполагает возможность появления (пропуска) ошибок даже во время компиляции. В частности, банальные опечатки могут серьёзно затянуть процесс.
Ограниченная функциональность. Вполне логично, что язык, созданный в прошлом столетии, не может покрыть ту функциональность, что присуща современным конкурентам.
Не самая высокая производительность, опять-таки вызванная динамической типизацией.
Swift
Краткое описание. В 2014 году специалисты Apple представили миру замену привычному Objective-C. Среди преследуемых целей были заявлены повышенная читаемость кода и устойчивость к ошибкам разработчика. Что получилось по факту, давайте посмотрим.
Для написания приложения требуется меньше кода, хотя бы просто потому, что здесь реализован упрощенный принцип работы с повторяющимися строками и заявлениями.
Удобен для чтения. Стандартное достоинство любого современного языка.
Больше возможностей по сравнению с Objective-C, в частности возможность управлять памятью.
Полноценное взаимодействие с кодом, написанным на Objective-C.
Повышенная безопасность. Это выражается и в обработке указателей, и в дотошности компилятора, и в том, что в саму компиляцию можно встроить опциональную переменную nil для обеспечения обратной связи.
Из-за молодости языка и не переведённых на Swift кодов OS X и iOS требуется хотя бы минимальное знание Objective-C;
Компилятор выдаёт излишние и просто сбивающие с толку ошибки, которые разработчику, пришедшему с других языков покажутся как минимум необычными.
Взглянув на все плюсы и минусы, превосходство Swift сомнений не вызывает. Но что говорит статистика?
Обзор мнений и статистики
GitHub, периодически публикующий статистику по созданным исходникам кода, утверждает, что на сегодня Swift уже на самой вершине.
Покопавшись на портале Quora, ярые сторонники Objective-C смогут поднять себе настроение, прочитав сколько Swift уступает по производительности другим языкам.
Большинство профессиональных разработчиков, отвечая на вопрос “какой язык учить: Swift или Objective-C?”, уверенно отвечает — оба.
Что касается мнения крупных порталов, то здесь мнение единодушно: вряд ли вы найдете хоть одну статью, где победу в сравнении одерживает Objective-C. Исключительно Swift. Именно поэтому мы приглашаем вас на интенсив по основам Swift.
Некоторые преимущества есть у языка Objective-C, да и опытные разработчики склонны идеализировать его. Но от тотального яблочного господства Swift отделяет время и кропотливая работа создателей над недостатками. Ведь, довольно логично, что язык, явившийся миру всего пару лет назад должен пройти непростую стадию народной критики и доработки, прежде чем взойти на престол. А Objective-C постепенно уйдёт в историю, оставив о себе лишь добрую память.
Источник
Objective-C id as Swift Any
Swift 3 interfaces with Objective-C APIs in a more powerful way than previous versions. For instance, Swift 2 mapped the id type in Objective-C to the AnyObject type in Swift, which normally can hold only values of class types. Swift 2 also provided implicit conversions to AnyObject for some bridged value types, such as String , Array , Dictionary , Set , and some numbers, as a convenience so that the native Swift types could be used easily with Cocoa APIs that expected NSString , NSArray , or the other container classes from Foundation. These conversions were inconsistent with the rest of the language, making it difficult to understand what exactly could be used as an AnyObject , resulting in bugs.
In Swift 3, the id type in Objective-C now maps to the Any type in Swift, which describes a value of any type, whether a class, enum, struct, or any other Swift type. This change makes Objective-C APIs more flexible in Swift, because Swift-defined value types can be passed to Objective-C APIs and extracted as Swift types, eliminating the need for manual “box” types. These benefits also extend to collections: Objective-C collection types NSArray , NSDictionary , and NSSet , which previously only accepted elements of AnyObject , now can hold elements of Any type. For hashed containers, such as Dictionary and Set , there’s a new type AnyHashable that can hold a value of any type conforming to the Swift Hashable protocol. In summary, the following type mappings change from Swift 2 to Swift 3:
Objective-C | Swift 2 | Swift 3 |
---|---|---|
id | AnyObject | Any |
NSArray * | [AnyObject] | [Any] |
NSDictionary * | [NSObject: AnyObject] | [AnyHashable: Any] |
NSSet * | Set | Set |
In many cases, your code will not have to change significantly in response to this change. Code that in Swift 2 relied on value types implicitly converting to AnyObject will continue to work as-is in Swift 3 by passing as Any . However, there are places where you will have to change the declared types of variables and methods and get the best experience in Swift 3. Also, if your code is explicitly using AnyObject or Cocoa classes such as NSString , NSArray , or NSDictionary , you will need to introduce more explicit casts using as NSString or as String , since the implicit conversions between the objects and value types are no longer allowed in Swift 3. The automatic migrator in Xcode will make minimal changes to keep your code compiling when moving from Swift 2 to 3, but the result may not always be the most elegant thing. This article will describe some of the changes you may need to make, as well as some pitfalls to look out for when changing your code to take advantage of id as Any .
Overriding methods and conforming to protocols
When subclassing an Objective-C class and overriding its methods, or conforming to an Objective-C protocol, the type signatures of methods need to be updated when the parent method uses id in Objective-C. Some common examples are the NSObject class’s isEqual: method and the NSCopying protocol’s copyWithZone: method. In Swift 2, you would write a subclass of NSObject conforming to NSCopying like this:
In Swift 3, in addition to making the naming change from copyWithZone(_:) to copy(with:) , you will also need to change the signatures of these methods to use Any instead of AnyObject :
Untyped Collections
Property lists, JSON, and user info dictionaries are common in Cocoa, and Cocoa natively represents these as untyped collections. In Swift 2, it was necessary to build Array , Dictionary , or Set with AnyObject or NSObject elements for this purpose, relying on implicit bridging conversions to handle value types:
Alternatively, you could use the Cocoa container classes, such as NSDictionary :
In Swift 3, the implicit conversions are gone, so neither of the above snippets will work as is. The migrator may suggest individually converting each value using as conversions to to keep this code working, but there’s a better solution. Swift now imports Cocoa APIs as accepting collections of Any and/or AnyHashable , so we can change the collection type to use [AnyHashable: Any] instead of [NSObject: AnyObject] or NSDictionary , without changing any other code:
The AnyHashable Type
Swift’s Any type can hold any type, but Dictionary and Set require keys that are Hashable , so Any is too general. Starting with Swift 3, the Swift standard library provides a new type AnyHashable . Similar to Any , it acts as a supertype of all Hashable types, so values of String , Int , and other hashable types can be used implicitly as AnyHashable values, and the type inside an AnyHashable can be dynamically checked with the is , as! , or as? dynamic cast operators. AnyHashable is used when importing untyped NSDictionary or NSSet objects from Objective-C, but is also useful in pure Swift as a way of building heterogeneous sets or dictionaries.
Explicit Conversion for Unbridged Contexts
Under certain limited circumstances, Swift cannot automatically bridge C and Objective-C constructs. For example, some C and Cocoa APIs use id * pointers as “out” or “in-out” parameters, and since Swift is not able to statically determine how the pointer is used, it cannot perform the bridging conversions on the value in memory automatically. In cases like this, the pointer will still appear as an UnsafePointer . If you need to work with one of these unbridged APIs, you can use explicit bridging conversions, written explicitly using as Type or as AnyObject in your code.
Additionally, Objective-C protocols are still class-constrained in Swift, so you cannot make Swift structs or enums directly conform to Objective-C protocols or use them with lightweight generic classes. You will need to explicit convert String as NSString , Array as NSArray , etc. with these protocols and APIs.
AnyObject Member Lookup
Any does not have the same magic method lookup behavior as AnyObject . This may break some Swift 2 code that looked up a property or sent a message to an untyped Objective-C object. For example, this Swift 2 code:
will complain that description is not a member of Any in Swift 3. You can convert the value with x[0] as AnyObject to get the dynamic behavior back:
Alternatively, force-cast the value to the concrete object type you expect:
Swift Value Types in Objective-C
Any can hold any struct, enum, tuple, or other Swift type you can define in the language. The Objective-C bridge in Swift 3 can in turn present any Swift value as an id -compatible object to Objective-C. This makes it much easier to store custom Swift value types in Cocoa containers, userInfo dictionaries, and other objects. For example, in Swift 2, you would need to either change your data types into classes, or manually box them, to attach their values to an NSNotification :
With Swift 3, we can do away with the box, and attach the object directly to the notification:
In Objective-C, the CreditCard value will appear as an id -compatible, NSObject — conforming object that implements isEqual: , hash , and description using Swift’s Equatable , Hashable , and CustomStringConvertible implementations if they exist for the original Swift type. From Swift, the value can be retrieved by dynamically casting it back to its original type:
Be aware that, in Swift 3.0, some common Swift and Objective-C struct types will bridge as opaque objects instead of as idiomatic Cocoa objects. For instance, whereas Int , UInt , Double , and Bool bridge to NSNumber , the other sized numeric types such as Int8 , UInt16 , etc. only bridge as opaque objects. Cocoa structs such as CGRect , CGPoint , and CGSize also bridge as opaque objects even though most Cocoa API that works with them as objects expects them boxed in NSValue instances. If you see errors like unrecognized selector sent to _SwiftValue , that indicates that Objective-C code is trying to invoke a method on an opaque Swift value type, and you may need to manually box that value in an instance of the class the Objective-C code expects.
One particular issue to look out for is Optionals. A Swift Any can hold anything, including an Optional, so it becomes possible to pass a wrapped Optional to an Objective-C API without checking it first, even if the API is declared as taking a nonnull id . This will generally manifest as a runtime error involving _SwiftValue rather than a compile-time error. Swift 3.0.1 included in Xcode 8.1 beta handles number types, Objective-C structs, and Optionals transparently by implementing these proposals that address the aforementioned limitations in NSNumber , NSValue , and Optional bridging:
To avoid forward compatibility problems, you should not rely on implementation details of opaque objects of the _SwiftValue class, since future versions of Swift may allow more Swift types to bridge to idiomatic Objective-C classes.
Linux Portability
Swift programs running on Linux with the Swift Core Libraries use a version of Foundation natively written in Swift, without an Objective-C runtime to bridge to. id -as- Any allows the Core Libraries to use the native Swift Any and standard library value types directly, while remaining compatible with code on Apple platforms using the Objective-C Foundation implementation. Since Swift does not interoperate with Objective-C on Linux, there is no support for bridging conversions such as string as NSString or value as AnyObject . Swift code that intends to be portable across Cocoa and the Swift Core Libraries should use the value types exclusively.
Learning More
id -as- Any is a great example of a Swift language improvement inspired by user feedback with earlier versions of Swift and refined by review from the open Swift Evolution process. If you want to learn more about the motivations and design decisions behind id -as- Any , the original Swift Evolution proposals are available on GitHub in the swift-evolution repository:
The net result is that Swift is a more consistent language, and Cocoa APIs become more powerful when used from Swift.
Источник