foreword
- As a language that can call each other with Objective-C, Swift also has some types and features of the C language. If your code needs it, Swift also provides a programming method that mixes programming with common C code structures.
1. Basic data types
Swift provides some basic types that are
char,int,float,double
equivalent Swift primitive data types. However, there is no implicit conversion between these Swift core primitive types, egInt
. Therefore, use these types only when your code explicitly requires them, andInt
use you want.Type C Swift type bool
CBool
char, signed char
CChar
unsigned char
CUnsignedChar
short
CShort
unsigned short
CUnsignedShort
int
CInt
unsigned int
CUnsignedInt
long
CLong
unsigned long
CUnsignedLong
long long
CLongLong
unsigned long long
CUnsignedLongLong
wchar_t
CWideChar
char16_t
CChar16
char32_t
CChar32
float
CFloat
double
CDouble
2. Enumeration
Swift introduces any C-style enumeration type marked
NS_ENUM
with . This means that whether enum values are defined in the system framework or in custom code, when they are imported into Swift, their prefix names will be truncated.- Swift also introduced options marked with
NS_OPTIONS
macros . While options behave like the introduced enumerations, options can also support some bit manipulations, eg&,| 和 ~
. In Objective-C, you set the flag to be always zero (0) with an empty option. In Swift, use nil for no options.
Look at this Objective-C enum
// Objective-C typedef NS_ENUM(NSInteger, UITableViewCellStyle) { UITableViewCellStyleDefault, UITableViewCellStyleValue1, UITableViewCellStyleValue2, UITableViewCellStyleSubtitle };
Do this in Swift
// Swift enum UITableViewCellStyle: Int { case Default case Value1 case Value2 case Subtitle }
When you need to point to an enum value, use the enum name starting with a dot (.)
// Swift let cellStyle: UITableViewCellStyle = .Default
3. Pointer
Swift avoids letting you directly access pointers whenever possible. However, Swift also provides you with a variety of pointer types when you need to manipulate memory directly. The following table uses Type as a placeholder type name to represent the mapping of grammars.
For parameters, use the following mapping:
C syntax Swift syntax const void *
CConstVoidPointer
void *
CConstPointer<Type>
const Type *
CUnsignedChar
Type *
CMutablePointer<Type>
For multi-level pointers of return types, variable and parameter types, the following mappings are used:
C syntax Swift syntax void *
COpaquePointer
Type *
UnsafePointer<Type>
For class types, use the following mapping:
C syntax Swift syntax Type * const *
CConstPointer<Type>
Type * __strong *
CMutablePointer<Type>
Type **
AutoreleasingUnsafePointer<Type>
3.1 C mutable pointers
When a function is declared to accept
CMutablePointer<Type>
parameters , the function can accept any of the following types as parameters.nil
, passed in as a null pointer- a value of
CMutablePointer<Type>
type - an input-output expression whose operand is an lvalue of
Type
type , passed in as the memory address of this lvalue An input and output
Type[]
value , passed in as the start pointer of an array, and whose lifetime will be extended during this callIf you declare a function like this
// Swift func takesAMutablePointer(x: CMutablePointer<Float>) { /*...*/ }
Then you can use any of the following ways to call this function
// Swift var x: Float = 0.0 var p: CMutablePointer<Float> = nil var a: [Float] = [1.0, 2.0, 3.0] takesAMutablePointer(nil) takesAMutablePointer(p) takesAMutablePointer(&x) takesAMutablePointer(&a)
When a function is declared with a
CMutableVoidPointer
parameter , then the function accepts any operandCMutablePointer<Type>
of similar type .Type
If you define a function like this
// Swift func takesAMutableVoidPointer(x: CMutableVoidPointer) { /*...*/ }
Then you can use any of the following ways to call this function
// Swift var x: Float = 0.0, y:Int = 0 var p: CMutablePointer<Float> = nil, q: CMutablePointer<Int> = 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)
3.2 C constant pointers
When a function is declared to accept
CConstPointer<Type>
parameters , the function can accept any of the following types as parameters.nil
, passed in as a null pointer- one , or the value converted
CMutablePointer<Type>,CMutableVoidPointer,CConstPointer<Type>,CConstVoidPointer
to if necessaryCConstPointer<Type>
AutoreleasingUnsafePointer<Type>
- an input-output expression whose operand is an lvalue of
Type
type , passed in as the memory address of this lvalue an
Type[]
array value, passed in as the start pointer of an array whose lifetime will be extended during this callIf you define a function like this
// Swift func takesAConstPointer(x: CConstPointer<Float>) { /*...*/ }
Then you can use any of the following ways to call this function
// Swift var x: Float = 0.0 var p: CConstPointer<Float> = nil takesAConstPointer(nil) takesAConstPointer(p) takesAConstPointer(&x) takesAConstPointer([1.0, 2.0, 3.0])
When a function is declared with a
CConstVoidPointer
parameter , then the function accepts any operandCConstPointer<Type>
of similar type .Type
If you define a function like this
// Swift func takesAConstVoidPointer(x: CConstVoidPointer) { /*...*/ }
Then you can use any of the following ways to call this function
// Swift var x: Float = 0.0, y: Int = 0 var p: CConstPointer<Float> = nil, q: CConstPointer<Int> = nil takesAConstVoidPointer(nil) takesAConstVoidPointer(p) takesAConstVoidPointer(q) takesAConstVoidPointer(&x) takesAConstVoidPointer(&y) takesAConstVoidPointer([1.0, 2.0, 3.0]) takesAConstVoidPointer([1, 2, 3])
3.3 Automatic release of unsafe pointers
When a function is declared to accept
AutoreleasingUnsafePointer<Type>
parameters , the function can accept any of the following types as parameters.nil
, passed in as a null pointer- a
AutoreleasingUnsafePointer<Type>
value An in-out expression whose operands are raw, copied into a temporary unowned buffer, the address of the buffer passed to the call, and on return, the value in the buffer is loaded, saved, and reallocated to the operand.
Note: This list does not contain arrays.
If you define a function like this
// Swift func takesAnAutoreleasingPointer(x: AutoreleasingUnsafePointer<NSDate?>) { /*...*/ }
Then you can call this function in any of the following ways:
// Swift var x: NSDate? = nil var p: AutoreleasingUnsafePointer<NSDate?> = nil takesAnAutoreleasingPointer(nil) takesAnAutoreleasingPointer(p) takesAnAutoreleasingPointer(&x)
Note: C function pointers were not introduced by Swift.
4. Global constants
- Global constants defined in C and Objective-C language source files are automatically imported by Swift compilation as Swift global constants.
5. Preprocessing instructions
- The Swift compiler does not include a preprocessor. Instead, it makes full use of compile-time properties to generate configuration and language features to accomplish the same functionality. So Swift doesn't introduce preprocessor directives.
5.1 Simple macros
A macro constant defined by the
#define
directive can be replaced by a global constant in Swift. Since simple macros used to define constants are directly mapped to Swift globals, the Swift compiler automatically introduces simple macros defined in C or Objective-C source files.For example: a global definition
#define FADE_ANIMATION_DURATION 0.35
canlet FADE_ANIMATION_DURATION = 0.35
be .
5.2 Complex macros
- Complex macros used in C and Objective-C do not have corresponding definitions in Swift. Complex macros are those macros that are not used to define constants, but are used to define functions that contain parentheses ( ). The complex macros you use in C and Objective-C are there to avoid the constraints of type checking and duplication of the same code. However, macros can also create bugs and refactoring difficulties. In Swift you can use functions and generics directly to achieve the same effect. Therefore, complex macros defined in C and Objective-C source files cannot be used in Swift.
5.3 Compile configuration
Swift code and Objective-C code are conditionally compiled in different ways. Swift code can be conditionally compiled based on the evaluation profile of the build configuration. The build configuration includes
true
andfalse
literals, command-line flags, and the platform test functions in the table below. You can-D <#Flag#>
specify command line flags with .function valid parameters os()
OSX, iOS
arch()
x86_64, arm, arm64, i386
- Note:
arch(arm)
The build configuration is not returned for 64-bit arm devices, and the build configuration is returned whentrue
the code is run on an iOS simulator that is 32-bit .arch(i386)
true
- Note:
A simple conditional compilation requires the following code format.
#if build configuration statements #else statements #endif
A declaration by zero or more valid Swift statements
statements
, which can include expressions, statements, and control flow statements. You can add additional build configuration requirements, conditional compilation instructions with&&
and||
operators!
and operators, and conditional control blocks#elseif
.#if build configuration && !build configuration statements #elseif build configuration statements #else statements #endif
Contrary to the C compiler's conditional compilation, Swift conditional compilation statements must be entirely self-contained and syntactically valid blocks of code. This is because Swift code is all syntax checked even if it is not compiled.