Swift Interoperability: API interaction with C (Swift version 2.0)-B

Source: Internet
Author: User
Tags bitwise



section contains content:


    • Basic data type (Primitive Types)

    • Enumeration (enumerations)

    • Pointer (Pointer)

    • Global Constants (Globals Constants)

    • preprocessing directives (preprocessor directives)


As part of interoperability with the Objective-c language, Swift also maintains compatibility with some types and features of the C language. If your code is needed, Swift also provides some ways to use common c structures and patterns.



Basic data types



Swift provides a number of types that correspond to the basic types of C languages such as char,int,float and double. However, there is no implicit conversion between these types and the swift core base type, such as Int. Therefore, only use these types when your code is explicitly required, and you should use int for any other possible scenario.






Enumeration



Any C-style enumeration declared with macro Ns_enum will be imported into a Swfit enumeration type by Swfit. Whether the enumeration values are defined in the system framework or in their own code, when they are imported into swift, their prefix names are truncated.



For example, look at the declaration of this OBJECTIVE-C enumeration:


    //Objective-C
    typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
        UITableViewCellStyleDefault,
        UITableViewCellStyleValue1,
        UITableViewCellStyleValue2,
        UITableViewCellStyleSubtitle
    };


In Swift, it is imported as such:


  //Swift
    enum UITableViewCellStyle: Int {
        case Default
        case Value1
        case Value2
        case Subtitle
    }


When you need to use an enumeration value, use an enumeration name that begins with a dot (.):


   //Swift
    let cellStyle: UITableViewCellStyle = .Default


Option set
For a C-style enumeration that uses the macro ns_options declaration, swift imports it as a swfit option set type. An option set, like an enumeration, truncates the prefix, leaving only the name of the option value.



For example, look at the declaration of this objective-c option:


 //Objective-C
    typedef NS_OPTIONS(NSUInteger, NSJSONReadingOptions) {
        NSJSONReadingMutableContainers = (1UL << 0),
        NSJSONReadingMutableLeaves = (1UL << 1),
        NSJSONReadingAllowFragments = (1UL << 2)
    };


In Swift, it is imported as such:


 //Swift
    struct NSJSONReadingOptions : OptionSetType {
        init(rawValue: UInt)
        static var MutableContainers: NSJSONReadingOptions { get }
        static var MutableLeaves: NSJSONReadingOptions { get }
        static var AllowFragments: NSJSONReadingOptions { get }
    }


In Objective-c, an option set is a bitmask of integer values. You can use the bitwise OR operator (|) to combine option values, using the bitwise AND operator (&) to detect option values. Creates an option set that can use a constant value or an expression. An empty set of options is represented by a constant of.



In Swift, the option set is represented by a struct that follows the Optionsettype protocol, where each option value is a static variable. The option set is similar to the collection type set for Swift, and you can add an option value with the Insert (_:) or Unioninplace (_:) method, removing the option value with the Remove (_:) or Subtractinplace (_:) method. Use the CONTAINS (_:) method to detect the option value. The value of creating an option set can use an array literal, where the option value starts with a dot (.) as an enumeration. Create an empty set of options you can use an empty array literal, or you can call the default initialization function.


  //Swift
    let options: NSDataBase64EncodingOptions = [
        .Encoding76CharacterLineLength,
        .EncodingEndLineWithLineFeed
    ]
    let string = data.base64EncodedStringWithOptions(options)


Shared body



Swift only partially supports the C's common body (Union) type. Swift cannot access unsupported fields when importing a type of common or bit segment (bitfields) mixed with C, such as the Nsdecimal type of the foundation. However, parameters and/or return values for these types of C and Objective-c APIs are capable of being used in swift.



Pointer



Swift avoids giving you direct access to pointers as much as possible. However, when you need to manipulate memory directly, Swift also provides you with a variety of pointer types. The following table uses type as a placeholder for the type name.



For return types, variables and parameters, use the following form:






For class type, use the following form:






Constant pointer



When a function is declared to accept the Unsafepointer parameter, the function can accept any of the following types as arguments:


    • Nil, passed in as a null pointer;

    • A unsafepointer,unsafemutablepointer, or autoreleasingunsafemutablepointer value, which, if necessary, is converted to a value of unsafepointer;

    • A string value if the type is Int8 or UInt8. The string is automatically converted to UTF8 within a buffer, which is valid for the duration of the call;

    • An lvalue operand is a type input-output (inout) expression that is passed to the memory address of the left-hand value;

    • A [Type] value, passing in the starting pointer of the array, and its life cycle will be extended during this call.


If you define a function like this:


Swift func Takesapointer (x:unsafepointer) {/*...*/}


Then you can call this function using any of the following methods:


   //Swift
    var x: Float = 0.0
    var p: UnsafePointer = nil
    takesAPointer(nil)
    takesAPointer(p)
    takesAPointer(&x)
    takesAPointer([1.0, 2.0, 3.0])


If the function is declared to use a unsafepointer parameter, then the function accepts any operand of type Unsafepointer.? If you define a function like this:


   //Swift
    func takesAVoidPointer(x: UnsafePointer)  { /* ... */ }


Then you can call this function using any of the following methods:


  //Swift
    var x: Float = 0.0, y: Int = 0
    var p: UnsafePointer = nil, q: UnsafePointer = nil
    takesAVoidPointer(nil)
    takesAVoidPointer(p)
    takesAVoidPointer(q)
    takesAVoidPointer(&x)
    takesAVoidPointer(&y)
    takesAVoidPointer([1.0, 2.0, 3.0] as [Float])
    let intArray = [1, 2, 3]
    takesAVoidPointer(intArray)


Variable pointer



When a method is declared to accept the Unsafemutablepointer parameter, the function can accept any of the following types as arguments:


    • Nil, passed in as a null pointer;

    • A value of type unsafemutablepointer;

    • An input-output (inout) expression that has an lvalue operand of type types and is stored. The memory address of the left value is passed in;

    • A value for the [type] type of the input output, passing in the starting pointer of the array, and its life cycle will be extended during this call.


If you define a function like this:


  //Swift
    func takesAMutablePointer(x: UnsafeMutablePointer) { /*...*/ }


Then you can call this function using any of the following methods:


   //Swift
    var x: Float = 0.0
    var p: UnsafeMutablePointer = nil
    var a: [Float] = [1.0, 2.0, 3.0]
    takesAMutablePointer(nil)
    takesAMutablePointer(p)
    takesAMutablePointer(&x)
    takesAMutablePointer(&a)


If the function is declared with a unsafemutablepointer parameter, then the function accepts any operand of type unsafemutablepointer.



If you define a function like this:


//Swift
func takesAMutableVoidPointer(x: UnsafeMutablePointer)  { /* ... */ }


Then you can call this function using any of the following methods:


  //Swift
    var x: Float = 0.0, y: Int = 0
    var p: UnsafeMutablePointer = nil, q: UnsafeMutablePointer = nil
    var a: [Float] = [1.0, 2.0, 3.0], b: [Int] = [1, 2, 3]
    takesAMutableVoidPointer(nil)
    takesAMutableVoidPointer(p)
    takesAMutableVoidPointer(q)
    takesAMutableVoidPointer(&x)
    takesAMutableVoidPointer(&y)
    takesAMutableVoidPointer(&a)
    takesAMutableVoidPointer(&b)


Automatically release pointers



When a function is declared to accept the Autoreleasingunsafemutablepointer parameter, the function can accept any of the following types as arguments:


    • Nil, passed in as a null pointer;

    • A value of type autoreleasingunsafemutablepointer;

    • An input-output (inout) expression whose operand is first copied to a buffer without an owner, and the address of the buffer is passed to the called function. When the call returns, the value in the buffer is loaded, saved, and re-copied to the operand.


Note that the array is not included in this list.



If you define a function like this:


Swift func Takesanautoreleasingpointer (x:autoreleasingunsafemutablepointer) {/* ... */}


Then you can call this function using any of the following methods:


   //Swift
    var x: NSDate? = nil
    var p: AutoreleasingUnsafeMutablePointer = nil
    takesAnAutoreleasingPointer(nil)
    takesAnAutoreleasingPointer(p)
    takesAnAutoreleasingPointer(&x)


The type pointed to by the pointer is not bridged. For example, NSString * * Converted to Swift, is autoreleasingunsafemutablepointer<nsstring?> Rather than autoreleasingunsafemutablepointer<string?>.



function pointers



The C language function pointer is introduced into Swift in the form of a closure by calling convention, which is represented as @convention (c). For example, a C-language function pointer of type int (*) (void) is converted to Swift's @convention (c) ()-Int32.



When invoking a function that takes a function pointer as a parameter, the value passed to it can be a top-level swift function, either a closure literal, or nil. Only swift functions that conform to the C function pointer calling convention can be used to pass values to the parameter of a function pointer type. For example, the Core Foundation's cfarraycreatemutable (_:_:_:) function, which has a parameter of type cfarraycallbacks struct. This cfarraycallbacks struct is initialized with some function pointers:


  func customCopyDescription(p: UnsafePointer) -> Unmanaged! {
        // return an Unmanaged! value
    }
    let callbacks = CFArrayCallBacks(
        version: 0 as CFIndex,
        retain: nil,
        release: nil,
        copyDescription: customCopyDescription,
        equal: { (p1, p2) -> Boolean in
            // return Boolean value
        }
    )
    var mutableArray = CFArrayCreateMutable(nil, 0, callbacks)


In the above example, when the cfarraycallbacks is initialized, the retain and release parameters are nil, and the function customcopydescription is passed to the copydescription parameter. A closure literal is passed to equal as a parameter.



Global constants



Global constants defined in the C and Objective-c language source files are automatically introduced by Swift compilation and are global constants of Swift.



preprocessing directives



The Swift compiler does not contain pre-processors. Instead, it takes advantage of compile-time properties, build configurations, and language features to accomplish the same functionality. Therefore, Swift does not introduce pre-processing instructions.



Simple macro



In C and objective-c, you typically use the # define directive to define a simple constant, and in swift you can use global constants instead. For example: Define a constant of # define Fade_animation_duration 0.35, which is better if you use let Fade_animation_duration = 0.35来 in Swift. Because simple macros that define constants are directly mapped to Swift Global, the Swift compiler automatically introduces simple macros defined in C or objective-c source files.



Complex macros



The complex macros used in C and objective-c do not correspond to anything in Swift. Complex macros are macros that are not used to define constants, and function-type macros that contain parentheses. You use complex macros in C and objective-c to avoid the limitations of type checking or to avoid retyping a large number of boilerplate code. However, macros can also cause debug and refactoring to be more difficult. In Swift you can use functions and generics to achieve the same effect, without any compromise of grievance. Therefore, complex macros defined in the C and Objective-c source files are not available in Swift.



Build configuration



The SWIFT code uses the conditional compilation in a different way than the C, objective-c code. Swift code can be conditionally compiled based on a combination of build configurations. The build configuration includes true and false literals, command-line flags, and platform test functions in the following table. You can use-d <#flag#> to specify command-line flags.






Note: The build configuration arch (arm) does not return true for 64-bit ARM devices, and the build configuration arch (i386) returns True when compiling code for the 32-bit iOS emulator.



A simple conditional compilation can be like this code:


  #if build configuration
      statements
    #else
      statements
    #endif


A statements consisting of 0 or more valid Swift statements, which can include expressions, ordinary statements, and control-flow statements. You can use the && | | operator to add a new compilation condition to a conditional compilation statement, use the! operator to negate a condition, and use #elseif to add a compilation block:


 #if build configuration && !build configuration
      statements
    #elseif build configuration
      statements
    #else
      statements
    #endif


Conditional compilation differs, the statement that the swift condition compiles must be a separate, complete, syntactically valid block of code. This is because all swift codes will be checked for syntax, regardless of whether they are compiled or not.



Swift Interoperability: API interaction with C (Swift version 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.