Objective-C Programming - points on the Block

1. First of all, we had fast, what is Block?

Block is a piece of code that starts with ^, can have a return value, and the parameter list in the OC, but that no name.

So you can think of it as an anonymous function.

In fact, it Swift closures (the Closure) is the same.

Or, you learned .NET delegate of children's shoes to know it, and it almost commission concept.

It can all be passed in a method, as a parameter.

 

Block no arguments no return value:

[MyObject myMethodParam1: xx param2: ^{

  ...

}];

There have parameters Block return value:

[MyObject myMethodParam1: xx param2: ^BOOL(id param1, id param2) {

  ...

}];

 

Well, he said so much, we look at an example:

myDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@"Key - %@: Value - %@", key, value);
    if ([@"END" isEqualToString:key]) {
        *stop = YES;
    }
}];

The code above enumerate a dictionary of key-value pairs, known encountered END key to exit the loop, otherwise enumerate all pairs.

 

2. Block Can we use a variable declared outside the scope of Block it?

The answer is yes, but it is read-only, if you want to modify this variable will compile error.

We still look at the top part of the code examples in the cycle, we have added an external variable, you want to make early termination Block

BOOL stopEarly = NO;
double stopValue = 100.2;
[myDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@"Key - %@: Value - %@", key, value);
    if ([@"END" isEqualToString:key] || [value doubleValue] == stopValue) {
        *stop = YES;
        stopEarly = YES; // 这段代码编译会出错!!
    }
}];

Block within the above code stopValue variable read without any problems, but when we attempt to modify the value of the variable in Block stopEarly, compiling a mistake!

 

If so, we insisted on the outside of the Block modify variables, is not it?

The answer is yes.

We want to use __block keyword, the principle is the use of the keyword, we can put variables outside the block from the stack moved to the heap, so that you can use within the Block.

When the Block, variable back to the stack.

Or the above code, we subject to amendments, as follows:

__block BOOL stopEarly = NO;
double stopValue = 100.2;
[myDict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) {
    NSLog(@"Key - %@: Value - %@", key, value);
    if ([@"END" isEqualToString:key] || [value doubleValue] == stopValue) {
        *stop = YES;
        stopEarly = YES; 
    }
}];

if (stopEarly)
    NSLog(@"Block提前终止了!");

 

3. When we send a message to an object in the Block, the system creates a strong pointer to the object

The strong pointer to the Block will remain beyond their scope, it does not exist.

 

4. Block Array

Property (nonatomic, strong) NSMutableArray * blockArray; 

...
 - ( void ) {the someMethod 
    [self.blockArray addObject: ^ { 
        ... 
    }]; 
} 

// Get array block and call 
void (^ doIt) ( void ) = self.blockArray [ 0 ]; 
doIt ();

 

The Common Block results in a circular reference (Memory Cycle) scenario

As we mentioned earlier:

When we send a message to an object in the Block, the system creates a strong pointer to the object

The strong pointer to the Block will remain beyond their range.

In other words, all the objects within the Block, will retain their memory on the heap, that is to say, Block will be retained

Strong point pointers to these objects (strong pointer).

 

Let's look at the following code:

@property (nonatomic, strong) NSMutableArray *blockArray;

...

// in the blockArray a strong pointer has been kept to the self object
// while self holds another strong pointer to blockArray
- (void) someMethod {
    [self.blockArray addObject:^{
        [self doSomething];
    }];
}

The above problem is the code: blockArray retained a strong reference point object class pointer, class objects, self is also retained

A reference pointer pointing blockArray strong.

We have a strong pointer to each other, they can not be released from the stack, which leads to a circular reference memory.

Solution:
In order to break the circular reference, we want to use a weakly typed local variables.
What does this mean?
Because local variables are strongly pointer types, we have retained a strong pointer to the heap, so we have to find a way to create a local variable of type weak pointer to
break the circular reference.
You can use keyword:
__weak
such as:
__weak MyClass * weakSelf = self;
so even if the self itself is a strong pointer type, and weakSelf we created has become a weak pointer types.

Thus, the above offending code we can make the following changes:

@property (nonatomic, strong) NSMutableArray *blockArray;

...

- (void) someMethod {
    __weak MyClass *weakSelf = self;

    [self.blockArray addObject:^{
        [weakSelf doSomething];
    }];
}

For such a block pointer to an object side becomes weak reserved pointer of type circular reference is broken!
This is a common solution, we must remember! !

 

Reproduced in: https: //www.cnblogs.com/davidgu/p/6079496.html

Guess you like

Origin blog.csdn.net/weixin_34362875/article/details/93803110