Because you are using "thing" inside the block, block will maintain a strong pointer to "thing" until the block goes out of scope or the block itself leaves the heap (i.e. no one points strongly to the block anymore) - which is what you want because blocks are first traveled and then the code is executed at some later point so you obviously do not want the block to loose the pointer to "thing" after the block is first traveled without execution.
Now, you have the block maintaining a strong pointer to "thing" and you have "thing" maintaining a strong pointer to the block through its property "setup". Neither "thing" nor the block can ever escape the heap now. That’s because there will always be a strong pointer to both of them (each other’s pointer). This is called a memory “cycle.”
The answer is to declare "thing" as weak:
Thing *thing = [[Thing alloc] init];
__weak Thing *weakThing = thing;
And use "weakThing" in the block. This solves the problem because now the block only has a weak pointer to "weakThing" . "thing" still has a strong pointer to the block through its property setup, but that’s okay.
Hope this was helpful