1. Block as a property of the class with copy
The declaration of the Block property requires a copy
modifier first, because only the copy
latter block is in the heap, and the lifetime of the block in the stack is bound to the stack.
< stacks: Local variables maintained by the system are present on the stack, whose life cycle is with the life cycle of the function >
< heap: The programmer applies for a space address, manually released by the programmer, and the lifecycle is controlled by the programmer >
Using retain is also possible, because the block's retain behavior is implemented by default with copy, the block variable is declared as a stack variable by default, in order to be able to use the block declaration outside the domain, so the block copy (copy) to the heap, So, for the block attribute declaration to be consistent with the actual operation, it is best to declare it as copy.
Another issue to be aware of is thread safety, which needs to be confirmed when declaring the Block property "is it possible for another thread to modify block when calling block?" "This problem, if it is determined that this does not happen, then the block attribute declaration can be used nonatomic
. If you're not sure (usually this is the case), then you first need to declare the Block property to be atomic
, that is, to guarantee the atomicity of the variable first (OBJECTIVE-C does not enforce the atomic nature of the pointer reading and writing).
However, atomic
to ensure that the basic atomicity is still not thread-safe, then at the time of invocation, the block must be assigned to local variables to prevent the block from suddenly changing. Because if this is not the case, even if you first judge that the Block property is not empty, before the call, once another thread has set the Block property empty, the program will be crash, the following code:
if (Self.myblock)
{
At this point, the Self.myblock may be changed to empty by another thread, causing crash
Note: Atomic only ensures the atomicity of Myblock, which is inherently non-thread-safe.
Self.myblock (123);
}
So the correct code is (ARC):
Myblocktype block = Self.myblock;
Block is now locally immutable.
if (block)
{
Block (123);
}
In the non-arc requires a manual retain
, otherwise if the property is empty, the local variable is a wild pointer, the following code:
Non-arc
Myblocktype block = [Self.myblock retain];
if (block)
{
Block (123);
}
[Block release];
2. Circular reference issues
Circular references are another common problem when using block.
Under Arc, because __block
the grab variable will be block retain
, so you must use a weak reference to solve the circular reference problem, IOS 5 can be used directly after the use of the __weak
only __unsafe_unretained
, the __unsafe_unretained
disadvantage is that the pointer released itself will not be empty. Example code:
__unsafe_unretained can be used before IOS 5
__unsafe_unretained typeof (self) weakself = self;
__weak typeof (self) weakself = self;
Self.myblock = ^ (int paramint)
{
Accessing the self member using weakself
[Weakself Anotherfunc];
};
In the non-arc, obviously cannot use weak reference, here can be used directly __block
to modify the variable, it will not be retain
the block, the reference code:
Non-arc
__block typeof (self) weakself = self;
Self.myblock = ^ (int paramint)
{
Accessing the self member using weakself
[Weakself Anotherfunc];
};
Block as a property of a class with copy