What the qualifiers do:
__block
this qualifier allows a closure to modify the value stored in the given variable.
__weak
is a reference to an object that does not prevent the object from being de-allocated.
__strong
is a reference to an object that does prevent the object from being de-allocated.
What you need to do:
__weak
doesn't do what you want because it doesn't prevent your array from being de-allocated after the current scope ends. Since you are making an async call, there is nothing preventing the run-time from reclaiming the memory used by the array before your block is executed.
__strong
will retain the object past the end of the current scope. This is what you want.
__block
will allow your block to modify the specified variable, however this isn't needed when referencing an instance variable since self
will be automatically retained.
In a reference-counted environment, by default when you reference an
Objective-C object within a block, it is retained. This is true even
if you simply reference an instance variable of the object. Object
variables marked with the __block storage type modifier, however, are
not retained.
Note: In a garbage-collected environment, if you apply both __weak and
__block modifiers to a variable, then the block will not ensure that it is kept alive. If you use a block within the implementation of a
method, the rules for memory management of object instance variables
are more subtle:
If you access an instance variable by reference, self is retained;
I think your problem lies here (relevant portions in bold):
You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier. __block storage is similar to, but mutually exclusive of, the register, auto, and static storage types for local variables.
__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or
created within the variable’s lexical scope. Thus, the storage will
survive the destruction of the stack frame if any copies of the blocks
declared within the frame survive beyond the end of the frame (for
example, by being enqueued somewhere for later execution). Multiple
blocks in a given lexical scope can simultaneously use a shared
variable.
As an optimization, block storage starts out on the stack—just like
blocks themselves do. If the block is copied using Block_copy (or in
Objective-C when the block is sent a copy), variables are copied to
the heap. Thus, the address of a __block variable can change over
time.
There are two further restrictions on __block variables: they cannot
be variable length arrays, and cannot be structures that contain C99
variable-length arrays.
Instead of an NSMutableArray
, try using a plain NSArray
using
+ (id)arrayWithObject:(id)anObject
.