Six, == Optinal== optional type (difficulty):
-
One of the characteristics of swift grammar is that it is a reflection of type safety, Int?,float! Note that the symbols in the back must be close to the type in front, and there can be no blank in the middle;
- Only Optional type can be null (nil in oc), which ensures that non-optional objects cannot be null, nor can they be assigned null.
- Any type can be an Optional type: let tupleTest: (Int, String)? = nil;
- When accessing attributes or instance methods, it is not necessary to judge whether the Optional object is empty every time, but to use Optional chain expression.
-
Basic use
- Optional: var testOp1 :Optional<Int8> = 1008611
- String? Here? No space in front
- Optional(name) If there is no value in an optional type, forced unpacking will cause an error
- Name! Optional(name) is optional type of forced unpacking.
// Declare the Optional variable testOptF type Int?, initialize to null var testOptF: Float? = nil var name: String? = nil // The optional chain operator is used here. // Here we will first determine whether testOptF is empty or not, and then perform a = 10 operation if it is not empty. // Otherwise, no operation will be performed. testOptF? = 3.1415// // This statement is the same as above. testOptF? += 10 // Here output: testOptF = nil print("testOptF = \(String(describing: testOptF))") testOptF! += 10 print("testOptF! = \(testOptF!)") if testOptF != nil { }
-
Forced dismantling:
Starting with code somewhere, you can make sure that the object is not empty, and then you can use mandatory disassembly; that is:! Indicates that its operand expression must not be empty
-
Optional binding
if let obj = Optional(0) { } //Or: if var obj = Optional(0) { }
This means that an object odj is declared and initialized using the following Opeional object expression. If obj is not empty, the statement in if is executed.
-
Introduction to Optional
- Optional is essentially a generic enumeration type that follows the ExpressibleByNilLiteral protocol; the Apple API defines it as follows:
public enum Optional<Wrapped> : ExpressibleByNilLiteral { case none /// The presence of a value, stored as `Wrapped`. case some(Wrapped) /// Creates an instance that stores the given value. public init(_ some: Wrapped) public func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U? public init(nilLiteral: ()) public var unsafelyUnwrapped: Wrapped { get } }
- You can see that there are two enumeration values: none denotes null values, and sone is stored here after assignment.
-
Common Ways and Use
-
Example
/// c Test Optional Types func testOptionals() -> () { let testOp1 :Optional<Int> = 1008611 print("Definition 1: Types and values before unpacking are:\(String(describing: testOp1))") // Let testInt8: Int8 = Int8 (testOp1!) error // print("int to int8 is:(testInt8)") let testOpt2 = Optional<String>("The second way of definition") print("Definition 2: Types and values before unpacking are:\(String(describing: testOpt2))") var testOpS : String? testOpS = "4334675444635" print("Definition 3: Types and values before unpacking are:\(String(describing: testOpS))") print("The types and values of forced unpacking are:\(testOpS!)") if let deOptionS = testOpS { print("The binding unpacking type and value are:\(deOptionS)") let reserint64 = Int64.init(deOptionS) print("convert to int64 Yes,\(reserint64 ?? 12)") if let tempint64 = reserint64 { let reserNSNum = NSNumber.init(value: tempint64) print("convert to NSNumber Yes,\(reserNSNum)") } } let refClosure: ((_ cunS : String?)-> String?)? = {(_ cus:String?)-> String? in print("\(cus!)-->This is a closure reference") return "test case" } let testClosWithOpt = refClosure!("Test parameters") print("Test closures and optional types======\(testClosWithOpt ?? "error")") let ss: NSString = "9876543210" let ll: Int64 = ss.longLongValue print("Turn into int64 Yes,"+"\(ll)") }
-
Output result
Definition 1: Types and values before unpacking are Optional(1008611) Definition 2: Types and values before unpacking are Optional("Second Definition") Definition 3: The type and value before unpacking is Optional("4334675444635"). The type and value of forced unpacking are 4334675444635 The binding unpacking type and value are 4334675444635 The conversion to int64 is 4334675444635 The conversion to NSNumber is 4334675444635 Test parameters - > This is a closure reference Test closures and optional types =========== test cases Converting to int64 is: 9876543210
-
Seven, function
- Definition
func function name (parameter type) - > return value{
code block
Return return value
}
- Reference labels
- The parameter label mainly provides the caller with the meaning of the passed argument, and the formal parameter name is mainly used to refer to the inside of the function.
- When there are multiple parameters, the parameter labels can be the same, but the parameters must be different.
func getName(user_id userID: Int) -> String{
return "haha"
}
//user_id Reference labels userID: Formal parameter name
func funNAME(_ name: Int) {
print("parameter is: \(name)")
}
funNAME(10)
Eight, class
-
Storage value
- If the type is a structure or class. Usually defined as an optional type
- If it is a basic attribute type, it is initialized directly at the time of definition.
class Persion : NSObject { // Storage attribute var name : String? var age : Int = 0 var money : Double = 0.0 //Calculated attribute var avarageSorce :Double { get { return money; } } // Class attribute static var courseCount : Int = 0 } //instantiation let stu = Persion() stu.name = "hhh" print(stu.avarageSorce) Persion.courseCount = 45//Class attributes must be invoked with classes
-
Attribute monitoring
var name : String?{ //In this method, the system has an identifier willSet { print(name ?? "haha") print(newValue ?? "444") } didSet { print(name!) print(oldValue ?? "haha") } }
-
Class initialization method
- > init method similar to oc
override init() { //Can not call, if not call the system will be called by default // super.init() } //Custom initialization constructor init(name : String , age : Int) { self.name = name; self.age = age; }
-
Class destructor
- This method can not be displayed and can only be automatically invoked with the reference count when it has passed the runtime.
- If a destructor is not shown, a default destructor is automatically added.
deinit { print("Father is destroyed") }
Nine, closure
-
Use
class testFun: NSObject { //Closure type: (parameter list) - > (parameter) func requ(callback : @escaping ()->()) -> () { DispatchQueue.global().async { () -> Void in let currentThread = Thread.current print("The current thread is\(currentThread)") DispatchQueue.main.async { () -> Void in let currentThread = Thread.current print("Callback the current thread to\(currentThread)") callback() } } } } //Direct call after instantiation testFunC?.requ(callback: { print("Start requesting data") })
-
Circular Reference Problem
weak var weakSelf = self;
Ten, agreement
- Using protocol to define protocols, protocols can only store computational properties and method declarations, which are equivalent to interfaces.
-
Use
-
Define protocol
//Define protocol protocol testProtoDelate { func getSomething(someThing someS:String?) -> String? } //Setting agent var testDelgate :testProtoDelate? //Trigger protocol let eatS = testDelgate?.getSomething(someThing: "Give me a call.") print("Are you all set? "+eatS!)
Agent Agent
//comply with the agreement let FunC = testFun() FunC.testDelgate = self // Implementing proxy in extension, testProtoDelate func getSomething(someThing someS: String?) -> String? { print("The agreement tells me \(someS!)") return "The phone has been called!" }
———————————— Modified in 2017-09-07 ----------------------------- 07
-
11. Namespaces
-
To avoid naming conflicts, Swift added a new concept called namespace.
- Namespaces in different projects are the name of the current project by default.
- Swift can solve the problem of renaming through namespaces. When developing Swift, we should try to use cocoapods to integrate the tripartite framework, which can effectively avoid duplication of class names.
- Creating a class through a string is different from OC. OC can create a class directly by class name, while Swift has to add a namespace if it wants to create a class by class name.
// 1. Dynamic acquisition of namespaces // Since only objects can be stored in dictionaries/arrays, is the type AnyObject? guard let name = Bundle.main.infoDictionary!["CFBundleExecutable"] as? String else { NJLog("Failed to get namespace") return } let cls: AnyClass? = NSClassFromString(name + "." + childControllerName) // If you want to create an object through a Class in Swift, you must tell the system the exact type of the Class. guard let typeCls = cls as? UITableViewController.Type else { NJLog("cls Can not be regarded as UITableViewController") return } // Create objects through Class let childController = typeCls.init() NJLog(childController)
Note: AnyObject? Because dictionaries or arrays store AnyObject types, if the key is written incorrectly or there is no corresponding value, it may cause an exception.
12. Access Level
-
swift provides five access levels:
If it is not limited by display modification of any access level, it defaults to internal.
Keyword | Range | Explain | Subclass inheritance | Storage attribute | Computational attributes and methods |
---|---|---|---|---|---|
open | Any other attributes and methods that are not final ized | It can only be used for class types and class type members. | can | Subclasses can override attributes and attributes observers of this attribute | Subclasses can be overridden |
public | Can be used by other modules, basic elements and attributes and methods in all file scopes | Can't inherit the class type it currently defines | can | Attributes and methods in class types cannot be modified | |
internal | Same as public, but only in the current module | Only source files in the current module can be accessed | |||
fileprivate | Same as public | Only visible within the scope of the current source file (introduced in 3.0) | |||
private | Modify attributes and methods in a type | Visible to the current type or object of that type |
== Note: No matter the class, enumeration or structure, its initialization method can only use public at the highest level. The cumulative destructor method can not be modified with any hierarchical orientation.==
-
The access level of an entity must be <== the minimum access level of the entity associated with it:
- A public object cannot be defined by a type that has a lower level of access than public; it may lead to a lower level where they should not be visible.
- open-level classes cannot inherit < their access level classes, and these low-level access classes expose their invisibility.
- The access level of a function cannot be higher than its return type and parameters.
- A class is limited to fileprivate, its members have fileprivate attribute by default, the class is limited to open, public, internal, its members default to internal access level;
- Custom type can limit the access level higher or lower than the type, but other file access can not break through the limit of this type.
The access level of a tuple is the lowest among its elements, and enumeration cannot define the qualified level of each element.
- The access level of subclasses can't be higher than that of parent classes, and subclass overhaul can raise the limit level but can't reduce it.
———————————— Modified in 2017-09-11---------------