Attributes

Attributes

There are two features in Swift, which are used to decorate declarations and types. Features provide more information about declarations and types. For example, a function declared with the discardableResult feature indicates that although the function has a return value, the compiler will not generate a warning if the return value is not used.

You can specify a feature in the following way, with the symbol @ followed by the name of the feature and any parameters received by the feature:

@Feature name

@Characteristic name (characteristic parameter)

Some declared features specify more information about the feature and how it modifies a particular declaration by receiving parameters. The parameters of these characteristics are written in parentheses, and their format is defined by the characteristics to which they belong.

Declared characteristics

The claim feature can only be applied to claims.

available

When the available feature is used in a claim, it means that the life cycle of the claim is relative to a specific platform and operating system version.

The available feature often appears with the parameter list, which has at least two feature parameters, separated by commas. These parameters start with one of the following platform names:

iOS
iOSApplicationExtension
macOS
macOSApplicationExtension
watchOS watchOSApplicationExtension tvOS tvOSApplicationExtension swift 

Of course, you can also use an asterisk (*) to indicate all the platforms mentioned above. Specify the available feature parameter of the Swift version, which cannot be represented by an asterisk.

The remaining parameters can appear in any order, and additional information about the declared life cycle can be added, including important events.

The unavailable parameter indicates that the statement is invalid on the specified platform. This parameter cannot be used when specifying the availability of the Swift version. The introduced parameter indicates the version from which the platform will introduce the statement. The format is as follows: introduced: version number

The version number consists of one to three positive integers, separated by periods.

The deprecated parameter indicates from which version the platform deprecated the declaration. The format is as follows: deprecated: version number

The optional version number consists of one or more positive integers, separated by periods. Omitting the version number indicates that the statement is currently deprecated, and no relevant information is given when the deprecation occurs. If you omit the version number, the colon (:) can also be omitted.

The obsoleted parameter indicates which version of the specified platform or language will be obsolete. When a statement is discarded, it is removed from the platform or language and can no longer be used. The format is as follows: obsoleted: version number

The version number consists of one to three positive integers, separated by periods.

The message parameter is used to provide text information. When using a deprecated or deprecated statement, the compiler will throw a warning or error message. The format is as follows: message: message content

The information content consists of a character string.

The renamed parameter is used to provide text information to indicate the new name of the renamed statement. When using the declared old name, the compiler will report an error and prompt for the new name. The format is as follows: renamed: new name

The new name consists of a string.

You can use the renamed parameter and the unavailable parameter for the available feature to indicate the availability of the declaration on different platforms and Swift versions. As shown below, it means that the declared name has changed between different releases of a framework or library. This combination indicates a compilation error in which the statement was renamed.

// 首发版本
protocol MyProtocol {
    // 这里是协议定义
}
// 后续版本重命名了 MyProtocol protocol MyRenamedProtocol {  // 这里是协议定义 } @available(*, unavailable, renamed:"MyRenamedProtocol") typealias MyProtocol = MyRenamedProtocol 

You can use multiple available features on a statement to specify the availability of the statement on different platforms and Swift versions. The compiler will only use the available feature if it matches the platform or language version specified in the available feature.

If the available feature specifies only one introduced parameter in addition to the platform name parameter, you can use the following shorthand syntax instead:

@available (platform name version number, *)

@available (swift version number)

The abbreviated syntax of the available feature can concisely express the availability of the statement on multiple platforms. Although these two forms are functionally the same, please use the shorthand syntax form whenever possible.

@available(iOS 10.0, macOS 10.12, *)
class MyClass {
    // 这里是类定义
}
当 available 特性需要同时指定 Swift 版本和平台可用性,需要使用单独的 available 特性来声明。  @available(swift 3.0.2) @available(macOS 10.12, *) struct MyStruct {  // 这里是结构体定义 } discardableResult

This feature is used in function or method declarations to suppress the warning that the return value of the function or method in the compiler is called without using the result.

dynamicCallable

This feature is used in classes, structures, enumerations, or protocols to treat instances of this type as callable functions. This type must implement one of the dynamicallyCall (withArguments :), dynamicallyCall (withKeywordArguments :) methods, or both.

You can call an instance of the dynamicCallable feature, just like calling a function with any number of parameters.

@dynamicCallable
struct TelephoneExchange {
    func dynamicallyCall(withArguments phoneNumber: [Int]) {
        if phoneNumber == [4, 1, 1] {
 print("Get Swift help on forums.swift.org")  } else {  print("Unrecognized number")  }  } }  let dial = TelephoneExchange()  // 使用动态方法调用 dial(4, 1, 1) // 打印“Get Swift help on forums.swift.org”  dial(8, 6, 7, 5, 3, 0, 9) // 打印“Unrecognized number”  // 直接调用底层方法 dial.dynamicallyCall(withArguments: [4, 1, 1]) 

The declaration of the dynamicallyCall (withArguments :) method must have at least one parameter that follows the ExpressibleByArrayLiteral protocol, such as [Int], and the return value type can be any type.

@dynamicCallable
struct Repeater {
    func dynamicallyCall(withKeywordArguments pairs: KeyValuePairs<String, Int>) -> String {
        return pairs
 .map { label, count in  repeatElement(label, count: count).joined(separator: " ")  }  .joined(separator: "\n")  } }  let repeatLabels = Repeater() print(repeatLabels(a: 1, b: 2, c: 3, b: 2, a: 1)) // a // b b // c c c // b b // a 

The dynamicallyCall (withKeywordArguments :) method declaration must have at least one parameter that follows the ExpressibleByDictionaryLiteral protocol, and the return value can be of any type. The Key of the parameter must follow the ExpressibleByStringLiteral protocol. The above example uses KeyValuePairs as the parameter type, so that the caller can pass in repeated parameter labels, and a and b are used multiple times in the call to repeat.

If you implement two dynamicallyCall methods at the same time, when the keyword argument is included in the method call, the dynamicallyCall (withKeywordArguments :) method will be called, otherwise the dynamicallyCall (withArguments :) method will be called.

You can only call dynamic call instances whose parameters and return values ​​match the dynamicallyCall method implementation. The call in the example below cannot be compiled because its dynamicallyCall (withArguments :) implementation does not accept KeyValuePairs <String, String> parameters.

repeatLabels(a: "four") // Error dynamicMemberLookup

This feature is used for classes, structures, enumerations, or protocols, allowing it to find members at runtime. This type must implement subscript (dynamicMemberLookup :) subscript.

In an explicit member expression, if no member is specified by name, the expression is understood as a call to the subscript (dynamicMemberLookup :) subscript of the type, passing a parameter that contains the member name string. The subscript receiving parameter can be either a key path or a member name string; if you implement both methods of subscript calling at the same time, then the key path parameter method shall prevail.

The subscript (dynamicMemberLookup :) implementation allows receiving keypath parameters of type KeyPath, WritableKeyPath or ReferenceWritableKeyPath. According to the ExpressibleByStringLiteral protocol, the subscript call receiving parameter is a member name string-in most cases, the subscript parameter is a String value. The subscript return value type can be any type.

Finding members dynamically based on member names can help us create a wrapper type that wraps data, but this type cannot be type checked at compile time, for example, when data in other languages ​​is bridged to Swift E.g:

@dynamicMemberLookup
struct DynamicStruct {
    let dictionary = ["someDynamicMember": 325,
                      "someOtherMember": 787]
 subscript(dynamicMember member: String) -> Int {  return dictionary[member] ?? 1054  } } let s = DynamicStruct()  // 使用动态成员查找 let dynamic = s.someDynamicMember print(dynamic) // 打印“325”  // 直接调用底层下标 let equivalent = s[dynamicMember: "someDynamicMember"] print(dynamic == equivalent) // 打印“true” 

Dynamically find members based on the key path, which can be used to create a package type that wraps data, which is type checked at compile time. E.g:

struct Point { var x, y: Int }

@dynamicMemberLookup
struct PassthroughWrapper<Value> {
 var value: Value  subscript<T>(dynamicMember member: KeyPath<Value, T>) -> T {  get { return value[keyPath: member] }  } }  let point = Point(x: 381, y: 431) let wrapper = PassthroughWrapper(value: point) print(wrapper.x) GKInspectable

Apply this property to expose a custom GameplayKit component property to the SpriteKit editor UI.

inlinable

This feature is used in the declaration of functions, methods, calculated attributes, subscripts, convenience constructors or destructors to expose the implementation of the declaration as part of the module's public interface. The compiler allows the inlinable symbol to be replaced with a copy of the symbol implementation at the call.

Inline code can interact with symbols at the public access level in any module, as well as symbols at the internal access level that mark the usableFromInline feature in the same module. Inline code cannot interact with private or fileprivate level symbols.

This feature cannot be used for declarations nested within functions, nor for declarations of fileprivate or private access levels. Functions and closures defined in inline functions are implicitly non-inline, even if they cannot mark the feature.

nonobjc

This feature is used for method, property, subscript, or constructor declarations. These declarations could have been used in Objective-C code, while using the nonobjc feature tells the compiler that this declaration cannot be used in Objective-C code.

This feature is used in extensions and has the same effect as adding this feature to each member in extensions that are not explicitly marked as objc features.

You can use the nonobjc feature to solve the looping problem of the bridge method in the class labeled objc. This feature also allows overloading the constructors and methods in the class labeled objc.

Methods marked with nonobjc characteristics cannot override methods marked with objc characteristics. However, methods marked with objc characteristics can override methods marked with nonobjc characteristics. Similarly, methods marked with the nonobjc feature cannot meet the method requirements in the protocol marked with the @objc feature.

NSApplicationMain

Using this feature on a class indicates that the class is an application delegate class. Using this feature has the same effect as calling the NSApplicationMain ( : :) function and passing the class name as the delegate class name to the function.

If you don't want to use this feature, you can provide a main.swift file and call the NSApplicationMain ( : :) function at the top level of the code , as shown below:

import AppKit NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) NSCopying

This feature is used to modify the storage variable attributes of a class. This feature will make the property's setting method use the copy of the incoming value for assignment, and this value is returned by the copyWithZone (_ :) method of the incoming value. The type of this attribute must conform to the NSCopying protocol.

The behavior of the NSCopying feature is similar to the copy feature in Objective-C.

NSManaged

This feature is used to modify instance methods or stored variable attributes in NSManagedObject subclasses, indicating that their implementation is dynamically provided by Core Data at runtime based on the relevant entity description. Core Data also provides storage for attributes marked with NSManaged characteristics at runtime. Applying this feature also means the objc feature.

objc

This feature is used to decorate any statement that can be expressed in Objective-C. For example, non-nested classes, protocols, non-generic enumerations (only enumerations whose primitive values ​​are integers), properties and methods (including access methods), constructors, destructors, and the following in classes and protocols Standard operator. The objc feature tells the compiler that this declaration can be used in Objective-C code.

This feature is used in extensions and has the same effect as adding this feature to each member in extensions that are not explicitly marked as nonobjc.

The compiler implicitly adds the objc attribute to subclasses of any class defined in Objective-C. However, subclasses cannot be generic and cannot inherit from any generic class. You can explicitly add the objc attribute to subclasses that meet these conditions to specify its Objective-C name, as described below. Protocols with objc added cannot inherit from protocols without this feature.

The objc feature is implicitly added in the following cases.

The parent class has the objc feature, and is rewritten as a subclass declaration. Follow the statement with the objc feature agreement. Declaration with IBAction, IBSegueAction, IBOutlet, IBDesignable, IBInspectable, NSManaged or GKInspectable features. If you apply the objc feature to enumerations, each enumeration use case will be exposed in Objective-C code in a combination of enumeration name and use case name. For example, there is a use case called Venus in the Planet enumeration, which is called PlanetVenus when it is exposed in Objective-C code.

The objc attribute has an optional parameter, which consists of an identifier. You can use this feature parameter when you want to expose the entity modified by objc to Objective-C with a different name. You can use this parameter to name classes, enumerated types, enumerated use cases, protocols, methods, access methods, and constructors. If you want to specify the name of a class, protocol, or enumeration under Objective-C, the name contains a three-letter prefix, such as the convention in Objective-C programming. The following example exposes the value method of the enabled attribute in ExampleClass to Objective-C. The name is isEnabled instead of its original attribute name.

class ExampleClass: NSObject {@objc var enabled: Bool {@objc (isEnabled) get {// return appropriate value}}} objcMembers

This feature is used in class declarations to apply the objc feature to all Objective-C compatible members of this class, extensions, subclasses, and subclass extensions.

Most code should use the objc feature to expose the required declaration. If you need to expose multiple declarations, you can group them into extensions that add the objc feature. The objcMembers feature facilitates a large number of libraries that use the introspection tools of the Objective-C runtime. Adding unnecessary objc features will increase the binary volume and affect performance.

requires_stored_property_inits

This feature is used in class declarations to require all stored properties in the class to provide default values ​​as part of their definition. The NSManagedObject attribute is inferred for any class inherited from it.

testable

This feature is used to modify the import statement when importing compile modules that allow testing, so that any entities marked with an internal access level modifier in the imported module can be accessed as if they were marked with a public access level modifier. Tests can also access classes and class members marked with internal or public access level modifiers, as if they were declared with open access modifiers.

UIApplicationMain

Using this feature on a class indicates that the class is an application delegate class. Using this feature is the same as calling the UIApplicationMain function and passing the class name as the delegate class name to the function.

If you do not want to use this feature, you can provide a main.swift file and call UIApplicationMain (code top level : : : :) function. For example, if your application uses a custom inherited from UIApplication sub-class as the main class, you can call the UIApplicationMain ( : : : :) function instead of using this feature.

usableFromInline

This feature is used in the declaration of functions, methods, calculated properties, subscripts, constructors or destructors to allow the symbol to be used for declaration of inline code in the same module. The declaration must have an internal access level modifier.

Like the public access modifier, this feature exposes the declaration as part of the module's public interface. Unlike public, the compiler does not allow code outside the module to refer to the declaration of the usableFromInline tag by name, even if the declaration symbol is exported it cannot be referenced. However, code outside the module can still exchange declaration symbols through the runtime.

Declarations marked as inlinable can be used implicitly in inline code. Although inlinable or usableFromInline can be used for internal declarations, they cannot be used at the same time.

warn_unqualified_access

This feature applies to top-level functions, instance methods, class methods, or static methods to trigger a warning when the function or method is used without a preceding qualifier (such as a module name, type name, instance variable, or constant). Using this feature can help reduce ambiguity in accessing functions of the same name in the same role.

For example, the Swift standard library includes min ( : :) top-level functions and min () methods for sequence comparison elements. The sequence method declaration uses warn_unqualified_access to reduce the ambiguity of using them in Sequence extensions.

Declarative features used by Interface Builder

The Interface Builder feature is a declarative feature used by Interface Builder to synchronize with Xcode. Swift provides the following Interface Builder features: IBAction, IBSegueAction, IBOutlet, IBDesignable, and IBInspectable. These features are conceptually the same as the corresponding features in Objective-C.

IBOutlet and IBInspectable are used to decorate the attribute declaration of a class, IBAction feature is used to decorate the method declaration of a class, IBDesignable is used to decorate the declaration of the class.

Applying IBAction, IBSegueAction, IBOutlet, IBDesignable or IBInspectable features all mean applying objc features at the same time.

Type characteristics

Type characteristics can only be used to modify types.

autoclosure

This feature delays expression evaluation by automatically encapsulating the expression into a parameterless closure. It can modify function parameters of type parameterless function type that returns the result type of the expression. For examples of how to use the autoclosure feature, see Automatic closures and function types.

convention

This feature is used to modify the function type, it points out the function calling convention.

The convention feature always appears with one of the following parameters.

The swift parameter is used to represent a Swift function reference. This is the standard calling convention for function values ​​in Swift.

The block parameter is used to indicate an Objective-C compatible block reference. The function value is used as a reference to a block object. The block is an id-compatible Objective-C object in which the calling function is embedded. The calling function uses C's calling convention.

The c parameter is used to represent a C function reference. The function value has no context and no capture function, and also uses the C calling convention.

Functions using the C function calling convention can also be used as functions using the Objective-C block calling convention, and functions using the Objective-C block calling convention can also be used as functions using the Swift function calling convention. However, only non-generic global functions, local functions, and closures that do not capture any local variables can be used as functions using the C function calling convention.

escaping

Use this feature in function or method declarations, which means that the parameters will not be stored for delayed execution, which will ensure that the parameters will not exceed the life cycle of the function call. There is no need to explicitly use self when accessing properties and methods in function types that use escaping to declare features.

Guess you like

Origin www.cnblogs.com/liuxiaokun/p/12684726.html