How do you handle 'require( …, bail)' stat

2019-06-16 18:26发布

问题:

I'm looking through some of the sample code for the Square Cam in Apple's sample code. I want to replicate some of it's functionality in a modern project using ARC. However, there are a ton of require statements such as:

BOOL success = (destination != NULL);
require(success, bail);

Which generates the compiler error:

Goto into protected scope.

My question is -- what is the appropriate way to handle such statements in a project using ARC?

回答1:

I had the same problem (with the same sample code). The code looked like this:

BOOL success = (destination != NULL);
require(success, bail);

//Initialise some variables

bail:
//Deal with errors

I added braces around the block with the declarations to make their scope clear:

BOOL success = (destination != NULL);
require(success, bail);
{
    // *** Initialise some variables ***
}
bail:
{
    //Deal with errors
}

And it solved the problem for me. Through looking at this I also learned you can sometimes expand build errors to get more detail.



回答2:

Apparently bail is in a scope with one or more __block variables; this is not allowed. See http://clang.llvm.org/compatibility.html#blocks-in-protected-scope for more. The solution proposed there is to limit the scope of the __block variable(s), by putting them in brace-delimited blocks. This may not work always; YMMV.



回答3:

I am adding some description for @Lewis42 answer.

If you don't put variable in its own scope, you bypass the initialisation of all variable after goto, and when ARC tries to clean it up, it will end up trying to release some random bit of memory.

If you don't want to put variables in their own scope make sure that any variable should not be declared below goto keyword.

Jumps to within __block variable scope

__block require special runtime initialization. A jump into the scope of a __block variable bypasses this initialization, leaving the variable's metadata in an invalid state.