Swift interoperability: Dances with Cocoa data types (Swift 2.0)-B

Source: Internet
Author: User



This section includes the following:


    • String (Strings)

    • Value (Numbers)

    • Collection Class (Collection Classes)

    • Error (Errors)

    • Foundation data type (Types)

    • Foundation Function (Foundation Functions)

    • Core Foundation


As part of OBJECTIVE-C Interoperability (interoperability), Swift provides a fast and efficient way to process COCOA data types.



Swift will automatically convert some of the objective-c types to Swift type and the swift type to the objective-c type. There are also data types that are interoperable in objective-c and Swift. Those data types that can be converted, or data types that have interoperability, are called bridged data types. For example, in Swift, we can pass an array value to a method that requires a Nsarray object. We can also convert a bridged type and a copy of it. When we use as to convert bridged types or those provided by constants and variables, Swift bridges their data types.



Swift also provides a simple and convenient way to cover the data types of the Foundation, and in the later swift language, we can feel the nature and unity in its syntax.



String



Swift is automatically converted in string and NSString types. This means that where the NSString object can be used, we can replace it with a string type of swift, which will also have the characteristics of their data type, such as string interpolation of string type, based on the Swift design API, and the various functions of the NSString class. Therefore, we almost no longer have to use the NSString class in our code. In fact, when Swift accesses the objective-c API, it replaces all nsstring types with string types. When we use the Swift class in our OBJECTIVE-C code, the API that is accessed replaces all string types with the NSString type.



To allow string conversions, simply import the foundation framework. For example, we can access capitalizedstring in a string in Swift, which is a property of the NSString class, and Swift will automatically convert the string to a NSString object to access this property. This property will even return a swift string type because it was replaced when it was imported.


1234 import Foundationlet greeting = "hello, world!"let capitalizedGreeting = greeting.capitalizedString// capitalizedGreeting: String = Hello, World!


If we do need to use a NSString object, we can use a Swift string value and convert it. The string type can always be converted from a NSString object to a swift string value, so it is not necessary to use an optional type converter (as?). We can also create a NSString object in a string by defining constants and variables.



import Foundationlet myString: NSString = "123"iflet integerValue = Int(myString as String) {    print("\(myString) is the integer \(integerValue)")}// prints "123 is the integer 123"


Localization



In Objective-c, a macro of the Nslocalizedstring class is used to locate a string. This collection of macros includes Nslocalizedstring,nslocalizedstringfromtable,nslocalizedstringfromtableinbundle, and Nslocalizedstringwithdefaultvalue. In Swift, only one function can be used to achieve the same function as the entire nslocalizedstring set, i.e. nslocalizedstring (key:tableName:bundle:value:comment:). This nslocalizedstring function provides a default value for the Tablename,bundle and value parameters, respectively. We can use it to replace macros.



Numerical



Swift automatically converts the identified numeric types int and float to nsnumber. Such conversions allow us to create a nsnumber based on one of these types:


let n = 42let m: NSNumber = n


We can also pass a value of type int, for example, to a parameter that requires a type of nsnumber. It is also important to note that NSNumber can contain many different types, so we cannot pass it to a single int value.



The types listed below are automatically converted to NSNumber:


    • Int

    • UInt

    • Float

    • Double

    • Bool


Collection Class



Swift automatically converts the Nsarray, Nsset, and nsdictionary classes to the equivalent classes in Swift: Array, set, and dictionary. This means that we will benefit from Swift's powerful algorithms and unique syntax to handle collections-the types of Foundation and Swift collections that can be converted to each other.



Array (Arrays)



Swift will automatically convert between the array type and the Nsarray type. When we convert from a Swift array to a Nsarray object, the converted result is an array of type [ObjectType]. If the Nsarray object does not indicate an exact parameter type, it will be converted to a swift array of type [Anyobject].



For example, we see the following OBJECTIVE-C statement:


@property NSArray* dates;- (NSArray *)datesBeforeDate:(NSDate *)date;- (void)addDatesParsedFromTimestamps:(NSArray *)timestamps;


So, the conversion to Swift is like this:



vardates: [NSDate]func datesBeforeDate(date: NSDate) -> [NSDate]func addDatesParsedFromTimestamps(timestamps: [String])


If an object is an instance of the Objective-c or Swift class, or if the object can be converted to another type, then the object belongs to an object of type Anyobject. We can convert any Nsarray object into a Swift array, because all Objective-c objects are of type Anyobject. Because of this, the Swift compiler will replace the Nsarray class with anyobject[] when accessing Objective-c APIs.



When we convert a Nsarray object to a Swift array, we can also convert the array coercion type to a specific type. Unlike converting from Nsarray class to anyobject[], converting objects from Anyobject types to explicit types does not guarantee success. Converting from anyobject[] to sometype[] Returns a value of optional, as it is not until the runtime compiler knows whether an object of Anyobject can be cast to a particular type. For example, if we know that a swift array contains only an instance of the UIView class (or a subclass of a UIView Class), we can cast an array element of type Anyobject to the UIView object. If the elements in the swift array are not objects of type UIView at run time, then the conversion returns nil.


let swiftyArray = foundationArray as AnyObject[]iflet downcastedSwiftArray = swiftArray as? UIView[] {    // downcastedSwiftArray contains only UIView objects}


We can also cast the Nsarray object to a specific type of swift array in the For loop:


foraView: UIView! infoundationArray {     // aView is of type UIView}


Note: This conversion is cast and generates an error message at run time if the conversion is unsuccessful.
When we convert from Swift arrays to Nsarray objects, the elements in the swift array must belong to Anyobject. For example, an int[] type of Swift array contains elements of the INT structure. The int type is not an instance of a class, but because the int type is converted to the NSNumber class, the int type belongs to the Anyobject type. Therefore, we can convert a swift array of type int[] to a Nsarray object. If an element in the Swift array does not belong to the Anyobject type, an error is generated at run time.



We can also create a Nsarray object from the Swift array. When we define a constant or variable as an Nsarray object and assign an array to it as an instance variable, Swift creates the Nsarray object instead of the swift array.


12 let schoolSupplies: NSArray = ["Pencil", "Eraser", "Notebkko"]// schoolSupplies is an NSArray object containing NSString objects


In the example above, the Swift array contains three string strings. Because of the conversion from a string type to a NSString class, the array literal is converted to a Nsarray object and successfully assigned to the Schoolsupplies variable.



When we use the Swift class or protocol in the OBJECTIVE-C code, the Access API replaces all types of swift arrays as Nsarray. If we pass a Nsarray object to Swift's API and require the array element to be a new type, the runtime generates an error. If the swift API returns a swift array that cannot be converted to the Nsarray type, the error is also generated.



Collection (sets)



In addition to arrays, Swift also automatically converts between the set type and the Nsset class. When we convert a Nsset object with a parameter type to the Swift collection, the result is a collection of set types. If the Nsset object does not indicate its argument type, it will be converted to a swift collection of set types.



For example, we see the following OBJECTIVE-C statement:



@property NSSet* words;- (NSSet *)wordsMatchingPredicate:(NSPredicate *)predicate;- (void)removeWords:(NSSet *)words;


So, convert to Swift, that's what it looks like:


varwords: Setfunc wordsMatchingPredicate(predicate: NSPredicate) -> Setfunc removeWords(words: Set)


We are able to convert all Nsset objects into Swift collections, because all Objective-c objects can be converted to anyobject. All Nsset objects can be converted to swift objects, so the Swift compiler will convert all Nsset classes to set when importing the Objective-c API. Similarly, when we use swift classes or protocols in Objective-c, the importer will remap the Swift collection to the Objective-c compatible type: Nsset object.



When we convert a Nsset object to a swift collection, you can also move the collection down to another specified type. Just like the down-turn of the swift array, the next turn of the Swift collection does not guarantee success. The result of converting to a specified type under set requires using the AS operator to ensure that it is an optional value.



We can still create a Nsset object directly from the swift array literal, which also follows the translation rules mentioned above. When we explicitly define a constant or variable as a Nsset object and use an array literal to assign a value, Swift will create a Nsset object instead of a swift collection.



Dictionary (Dictionaries)



Swift can also be converted automatically in the dictionary and Nsdictionary classes. When we convert a Nsdictionary object with a parameter type to a swift dictionary, the result is a dictionary of type [ObjectType]. If the Nsdictionary object does not indicate a parameter type, it will be converted to a swift dictionary of type [Nsobject:anyobject].



For example, we see the following OBJECTIVE-C statement:



@property NSDictionary* cachedData;- (NSDictionary *)fileSizesForURLsWithSuffix:(NSString *)suffix;- (void)setCacheExpirations:(NSDictionary *)expirations;


So, convert to Swift, that's what it looks like:



varcachedData: [NSURL: NSData]func fileSizesForURLsWithSuffix(suffix: String) -> [NSURL: NSNumber]func setCacheExpirations(expirations: [NSURL: NSDate])


We are able to convert all Nsdictionary objects into swift dictionaries, because all OBJECTIVE-C objects are compatible with Anyobject. Again, an object can be "compatible" with anyobject, meaning that it is an instance of Objective-c, or a swift class, or something that can be converted to one of these two. All Nsdictionary objects can be converted to the Swift dictionary, so the Swift compiler will replace all nsdictionary classes with [Nsobject:anyobject] when importing the Objective-c API. Similarly, when we use swift classes or protocols in Objective-c, the importer will remap the Swift dictionary to the Objective-c compatible type: Nsdictionary object.



When we convert a Nsdictionary object to a swift dictionary, you can also turn the dictionary into another specified type. Just like the next turn of the swift array, the next turn of the Swift dictionary does not guarantee success. The result of converting to a specified type under [Nsobject:anyobject] requires an as operator to ensure that it is an optional value.



When we perform a reverse conversion, that is, the Swift dictionary is converted to a Nsdictionary object, its key value must be an instance of a class, or it can be converted to an instance of a class.



We can still create a Nsdictionary object directly from the swift array literal, which also follows the translation rules mentioned above. When we explicitly define a constant or variable as a Nsdictionary object and use an array literal to assign a value, Swift will create a Nsdictionary object instead of a swift dictionary.



Error



Swift can automatically convert between the ErrorType type and the Nserror class, and the Objective-c method of error will be equivalent to the throw method in Swift, and the Swift method of error will occur by objecitive-c the error Convention, is also equivalent to the Objective-c method that produces the error.



Implementing the ErrorType protocol, and using the Swift enumeration type declared with the @objc attribute, results in a ns_enum declaration and a NSString constant that can set the corresponding error range in the resulting header file. For example, there are the following swift enumeration declaration codes:



@objc public enum CustomError: Int, ErrorType {    caseA, B, C}


Then, the Objectivive-c declaration in the corresponding generated header file is:


// Project-Swift.htypedef SWIFT_ENUM(NSInteger, CustomError) {  CustomErrorA = 0,  CustomErrorB = 1,  CustomErrorC = 2,};static NSString * const CustomErrorDomain = @"Project.CustomError";


For more information about error handling in the swift and Objective-c APIs, see error handling.



Foundation Data type



Swift also provides a simple and convenient overlay method to connect the data types defined in the Foundation framework. Using the overlay method in Cgsize and cgpoint, we can feel the nature and unity of Swift language in its syntax. For example, we can create a structure of type cgsize using the following syntax:


1 let size = CGSize(width: 20, height: 40)


The override method also allows us to invoke the structure function of the Foundation in a natural way.


123 let rect = CGRect(x: 50, y: 50, width: 100, height: 100)let width = rect.width    // equivalent of CGRectGetWidth(rect)let maxX = rect.maxY      // equivalent of CGRectGetMaxY(rect)


Swift can convert Nsuinteger and nsinteger to the int type. These types will become int types in the Foundation APIs. int is often used as consistently as possible in Swift, and when we ask for an unsigned integer type, the UINT type is always available.



Foundation functions



In Swift, NSLog can output information in the system console. We can use this function as in the syntax format used in OBJECTIVE-C.



NSLog("%.7f", pi)// Logs "3.1415927" to the console


At the same time, Swift also provides output functions such as print (_:). Thanks to the character interpolation mechanism of Swift, these functions are simple, crude and efficient. These functions do not output information in the system console, but are available when a call is required.



The Nsassert function is no longer present in Swift and is replaced by an assert function.



Core Foundation



The Core Foundation type in Swift is a mature class. When memory management annotations are present, Swift automatically manages the memory of the core foundation objects, including the core foundation objects that we instantiate. In Swift, we are free to transform the fundation and Core Foundation types. If we want to convert to bridge Foundation type First, then you can also bridge some toll-free bridged Core foundation types to the Swift standard library type.



Remap type (remapped Types)



When Swift imports the Core Foundation type, the compiler will remap the imported type name. The compiler removes REF from the end of each type name, because all Swift classes are reference types, so the suffix is redundant.



The Cftyperef type in the Core Foundation will remap the Anyobject type. So we used the cftyperef, now it should be replaced by Anyobject.



Memory Management Object (Managed Objects)



In Swift, the Core Foundation object returned from the annotated APIs is able to automate memory management-we no longer need to call our own cfretain,cfrelease, or cfautorelease functions.



If we return a Core Foundation object from our own C function and objective-c method, we need to annotate the object with cf_returns_retained or cf_returns_not_retained. We can also use the cf_implicit_bridging_enabled and cf_implicit_bridging_disabled macro commands to encapsulate C function declarations, which follow the management rules, naming rules of the core Foundation, To be able to export the memory management mechanism according to the naming fallback.



If we only invoke annotated APIs that do not return the Core Foundation objects indirectly, we can now skip the rest of this section. Otherwise, we continue to learn about unmanaged Core Foundation objects.



unmanaged objects (unmanaged Objects)



When Swift imports unannotated APIs, the compiler will not automatically manage the managed memory of the returned Core Foundation objects. Swift encloses these returned Core Foundation objects in a unmanaged structure. Objects that are indirectly returned to the Core Foundation are also unmanaged. For example, here is a unannotated C function:


CFStringRef StringByAddingTwoStrings(CFStringRef string1, CFStringRef string2)


This explains how Swift is imported:


1 func StringByAddingTwoStrings(CFString!, CFString!) -> Unmanaged!


Suppose we receive an unmanaged object from unannotated APIs, before we can use it, we have to convert it to a memory-managed object. In this regard, Swift can help us with memory management without having to do it ourselves. At the same time, the unmanaged structure provides two ways to convert an unmanaged object into a memory-managed object--takeunretainedvalue () method and a Takeretainedvalue () method. Both of these methods return the original, non-enclosing object type. We can choose which method is more appropriate based on the unretained or retained objects returned by the APIs we actually call.



For example, suppose there is a C function, which does not release the Cfstring object until the value is returned. Before using this object, we use the Takeunretainedvalue () function to convert it to an object that can be managed by memory.


12 let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue()// memoryManagedResult is a memory managed CFString


We can also use the Retain (), release (), and Autorelease () methods in an unmanaged object, but this practice is not recommended.



For more information, please refer to Memory Management Programming Guide in Core Foundation for memory Management programming guidance for Core Foundatio N section.



Swift interoperability: Dances with Cocoa data types (Swift 2.0)-B


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.