IOS swift3.0 closed-pack grammar collation
First, the concept of closure
There are OC basis know that the closure is actually OC inside the block, grammatical format is not the same, but the role is the same. It is used primarily for callback (asynchronous callbacks) or for communication between two classes. It's essentially a function, an executable block of code, but this function is not a name, that is, an anonymous function. You can also think of him as int, float, is a data type, a data type that can be passed as a parameter.
Second, the basic grammar
1, closure of the statement
Define a sum closure
//Closure type: (int,int)-> (int) Let
add: (int,int)-> (int) = {
(a,b) in return
A + b;
}
Executing a closure is equivalent to calling the function let result
= Add (1100);
Print closure return value print
("result=\ (Result)");
The closure type is determined by the parameter return value, such as the Add closure type (int,int)-> (INT), the arrow front bracket is a parameter type, multiple arguments are separated by commas, and the following parentheses return the value type.
Analysis of the above code, "=" to the left of "let add: (Int,int)-> (Int)" means to declare an add constant, add is a closure type, and this closure type is: (int,int)-> (int).
To the right of "=" is a block of code, the exact implementation of the closure, which is equivalent to assigning a value to the left add constant. Syntax format for code blocks:
{
(parameter 1, parameter 2) in
//code
}
The parameters and the code to be executed are separated by the keyword "in", and if the closure has no parameters, "() in" can be omitted directly:
You can also use the keyword "Typealias" to first declare the data type of a closure
Import Uikit
//Declare a closure type Addblock
typealias addblock = (int,int)-> (Int);
Class Viewcontroller:uiviewcontroller {
override func Viewdidload () {
super.viewdidload () Let
add: Addblock = {
(a,b) in return
A + b;
}
Let result = Add (1100);
Print ("result=\ (Result)");
}
3, closure of the use of
1, two classes of communication between
There are many ways to communicate between classes in iOS, which are commonly used: protocol proxies, notifications, and closures to be covered in this chapter. Because the protocol agent to use more trouble, but also to declare the Protocol method, but also to set the agent, the code steps too much, I generally do not use; Notice generally used for two completely unrelated class communication, you can one-to-many, but decoupling and too powerful, I generally is a specific occasion. So for the communication between the two classes, I usually use closures or blocks, which is relatively simple and quick.
Example program: Monitor the last Custom View button on the Listener controller
Interface effect
Code in CustomView class
Class Customview:uiview {
//Declaration of a property btnclickblock,type for closures optional type
//closure type: ()-> (), no parameters, no return value
var Btnclickblock: (()-> ())?;
Rewrite init (frame:cgrect) constructor
override Init (frame:cgrect) {
super.init (frame:frame);
Create button let
btn = UIButton (Frame:cgrect (x:15, y:15, width:80, height:32));
Btn.settitle ("button", for:. Normal);
Btn.backgroundcolor = Uicolor.blue;
Binding event
Btn.addtarget (Self, Action: #selector (Customview.btnclick), for:. Touchdown);
Add
addsubview (BTN);
button click event Function
func Btnclick () {
if Self.btnclickblock!= nil {
//Click button to perform closure
//Note: Property Btnclickblock is an optional type , you need to unpack
self.btnclickblock! () first
;
}
Required init? (Coder Adecoder:nscoder) {
FatalError ("Init (coder:) has not been implemented")
}
}
Controller the code in the class:
Class Viewcontroller:uiviewcontroller {
override func Viewdidload () {
super.viewdidload ()
// Create CustomView objects let
cutomeview = CustomView (Frame:cgrect (x:50, y:50, width:200, height:200));
Assign value to Cutomeview btnclickblock closure Property
Cutomeview.btnclickblock = {
///() in no parameters can be omitted
////When button is clicked the code block
is executed Print ("button clicked");
}
Cutomeview.backgroundcolor = Uicolor.yellow;
Add to Controller View
Self.view.addSubview (Cutomeview);
}
2, asynchronous callback (CallBack)
For example, to send a simple network request:
///defines a network request function//////-parameter urlstring: request interface String///-parameter succeed: Successful callback optional closure///-parameter failure: Failed callback optional closure func requestdata (any?) -> (Void))?, failure: (any?) -> (Void))?
{Let request = URLRequest (Url:url (string:urlstring)!); Send Network request nsurlconnection.sendasynchronousrequest (request, Queue:operationqueue ()) {(_, data, error) in if Erro r = = Nil {//request succeeded, execute a successful callback, and pass the data out succeed? (
data); }else{//Request failed, execute failed callback, and pass the error out failure? (
Error); }
}
}
Call function RequestData function
requestdata (urlstring: "Http://www.baidu.com", Succeed: {(data)-> (Void)
in//successful callback C3/>guard Let result = data as? Data else{return
;
}
Let SRT = NSString (Data:result, encoding:String.Encoding.utf8.rawValue);
Print (srt!)
}) {(Error)-> (Void) in
//failed callback
print (error);
}
Some special grammar of closure
1, trailing closure
The preceding parentheses can be omitted when the closure is the last argument of the function. Trailing closures have no special effect, simply a grammatical simplicity that increases readability.
Example: Define a function:
Second parameter: Closure (string)-> (Void)
func post (url:string,succesce: (String)->void) {
print ("Send Request");
SUCCESCE ("request Complete");
}
Execute function, normal wording:
Normal writing, second parameter, passing a closure
post ("http", Succesce: {
//Closure pass parameter
(JSON) in
//executing code
print (JSON);
});
Execution function, followed by the closure of the package:
Trailing closures, when the closure is the last parameter of a function, you can omit the preceding bracket
httptool.post ("http") {(JSON) in
print (JSON);
2. Escape closure
A name that looks very "fried" is actually very simple. When a closure is passed as a parameter to a function, we know it is generally used for asynchronous callbacks inside functions, which are called after the asynchronous task completes, and the function is executed quickly and returned, so the closure needs to escape for later callbacks.
Escape closures are generally used for callbacks to asynchronous functions, such as a successful callback of a network request and a failed callback. Syntax: Adds the keyword "@escaping" before the closure line parameter of a function.
Perhaps the careful person has found me the above example network request Why did not appear the keyword "@escaping", you can pull back to see a successful callback or failed callback, type is "((any?) -> (Void))? ", with a" in the back? " , this is a closed-pack optional type, not a closure type, so no keyword "@escaping" is required.
Suppose that a successful and failed callback is to be made into a closure type, and you are going to use it asynchronously, precede the parameter with the keyword, as follows:
Define a network request function
///
///-parameter urlstring: request interface String
///-parameter succeed: Successful callback closures need to be used asynchronously, preceded by the key The word @escaping is decorated to indicate that it is an escape closure
///-parameter failure: The failed callback closure is used asynchronously, preceded by a keyword @escaping modifier, indicating that it is an escape closure
func RequestData ( Urlstring:string,succeed: @escaping (any?) -> (Void), failure: @escaping (any?) -> (Void)) {let
request = URLRequest (Url:url (string:urlstring)!);
Send Network request
nsurlconnection.sendasynchronousrequest (Request, Queue:operationqueue ()) {(_, data, error) in
if Error = = Nil {
//request succeeded, execute a successful callback, and pass out the data
succeed;
} else{
//request failed, execute failed callback, and pass out error
failure (error);}
}
Suppose the success and failure of the callback to be made into a closure type, and you have to use it asynchronously, but you do not want to be in front of the parameters of the keyword, I am sorry, I do not have the means to compile a direct error!
Thank you for reading, I hope to help you, thank you for your support for this site!