SoFunction
Updated on 2025-04-06

Tutorial on using block in Objective-C and trailing closures in Swift

Preface

During project development, I often check how to write iOS closures because its syntax is too strange and the two languages ​​are written in different ways. I often get confused. I just record the commonly used writing methods.

Closure definition

A closure refers to a block of code that can contain free (not bound to a specific object) variable; these variables are not defined within this block of code or in any global context, but are defined in the environment where the block of code is defined (local variables). The term "closure" comes from a combination of the code block to be executed (because free variables are contained in the code block, these free variables and the objects they refer to are not released) and the computing environment (scope) that provides bindings to the free variables.

Blocks in OC and trailing closures in Swift both play the role of taking parameters as return values, which is often called callbacks.

1. Use of block

In OC blocks are mainly divided into three types, namely

(1)_NSConcreteGlobalBlock globally static,

(2) _NSConcreteStackBlock is saved in the stack, and then destroyed after the function scope is released.

(3) _NSConcreteMallocBlock is saved in the heap, retainCount == 0 is destroyed.

When using block, we roughly divide it into the following steps:

//1. Use typedef to define a blocktypedef void(^CallBack1)(); //No parameterstypedef void(^CallBack2)(NSString *test); //with parameters//2. Declaration via attribute@property (nonatomic, copy) CallBack callBack;
//3. Declare through function method- (void)functionCallBack:(CallBack)callBack;

In fact, if you write more skillfully, you can also define it together:

@property (nonatomic, strong) void(^ completed1)();//No parameters@property (nonatomic, strong) void(^ completed2)(NSString *test);//with parameters- (void) functionCallBack:(void(^)())completed1;//No parameters- (void) functionCallBack:(void(^)(NSString *test))completed2;//with parameters

2. Use of trailing closures

In Swift, a closure is a self-contained block of function code that can be used and passed in the code, equivalent to an anonymous function.

Then the trailing closure is the last parameter of this function, which is a closure, so it is stipulated that this closure can be written in the parentheses of the function or placed directly at the end for use, just like redefining this function once.

Moreover, its writing style is very similar to block:

//1. Use typealias to definetypealias functionBlock1 = () -> ()//No parameterstypealias functionBlock2 = (String) -> ()//with parameters//2. Declare the function bodyfunc blockTest1(complete: (functionBlock1)) -> () {
  complete()
}
func blockTest2(complete: (functionBlock2)) -> () {
  let re: String = "Cookie"
  complete(re)
}
//3.Use functionsblockTest1 {}
blockTest2{ (result) in
   print(result)
}

Similarly, if you write more skillfully, you can also define it together:

//1. Declare the function bodyfunc blockTest(complete: (_ result: String)->()) -> () {
  
  let re: String = "Cookie"
  complete(re)
}
//2.Use functionsblockTest { (result) in
   
   print(result)
}

In addition, the closure in swift also includes escape closures, which are executed only after the function returns. We say that the closure escapes from the function and is mostly used to make function callbacks, which is similar to Block in Objective-C. Automatic closure. When passing as a parameter to a function, the closure can be defined as an automatic closure (using the keyword @autoclosure). In this way, when passing the parameters, a piece of code (or a variable or expression) can be directly passed, and the system will automatically convert this code into a closure.

Summarize

The above is the entire content of this article. I hope that the content of this article has a certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.