Why is stop a BOOL pointer in enumerateObjectsUsingBlock:? [duplicate] - objective-c

This question already has an answer here:
What is the BOOL *stop argument for enumerateObjectsUsingBlock: used for?
(1 answer)
Closed 9 years ago.
I understand what the stop parameter is for, but I'm curious about why this is a BOOL * instead of just a BOOL. Is it because the value itself needs to exist outside of block scope, so that enumerateObjectsUsingBlock: has access to the value potentially assigned to it by the block itself?

To answer your question (though it looks like a dupe) the block needs to tell its caller to stop enumerating if it's found what it's looking for. There are two choices in C:
return YES to continue or return NO to stop.
Set a variable in the caller's scope, hence the BOOL *.
Apple chose the second approach, although I think the first approach is both simpler (one less parameter) and more intuitive.
It cannot be just BOOL as that only sets the local copy of the variable, not the variable in the caller's scope.

Related

Is it possible (and if so, how) to assign the return value of a block to a variable? [duplicate]

This question already has answers here:
Inline Block With Return Type
(4 answers)
Closed 7 years ago.
Is it possible to assign the return value of a block to a variable?
For example, I know this can be done:
NSString *(^sampleBlock)(void) = ^NSString *(void)
{
return #"sampleString";
};
NSString *string = sampleBlock();
But I would like to achieve something like (the following syntax is incorrect):
NSString *string = ^NSString *(void)
{
return #"sampleString";
};
I have been looking through several sites explaining block syntax, such as fuckingblocksyntax.com, but this case is not accounted for.
I know it can be done on a lot of ways, I just want THAT way, for readibility purposes.
Does anyone know if this is actually possible?
Thanks
Of course that is possible, but you have to actually execute the block by adding () at the end. Otherwise there is not really any return value that you can assign.
NSString *string = ^NSString *(void)
{
return #"sampleString";
}();
NSLog(#"%#", string);
Correctly outputs
sampleString
Look at it this way. The variable to which you are assigning exists now:
NSString *string = // ...
But the block is just a block: it's a mere function body, a container for code that might or might be called at some future time. Just when it (i.e. the code it contains) will be executed, if ever, is completely unknown:
^NSString *(void) {
return #"sampleString";
}
So you are trying to take an equals sign and unite, on the left, storage that exists now with, on the right, the running of code ten minutes from now, or a year from now, or never.
This is like some sort of time-warp paradox from a science fiction movie. You're asking the future running of the code to jump through a time-warp and arrive back here in the past and set this variable to something, now. This is like asking to meet, now, your son when your son is the age that you are now.
On the other hand, if you do what is suggested in the other answer, namely define the block and execute it, then both the execution and the assignment take place now. The block is merely something we pass through on the way to producing a string that is to be assigned to the variable. And this allows you to initialize a variable by means of several lines of code, inline. In Swift, for example, where functions are first-class citizens, such an idiom is extremely common:
let s : String = {
// ... do stuff here
return result
}()
And Swift even has a feature called lazy initialization, which allows the execution of the function and the initialization of the variable to be postponed until such time, if any, when some code actually asks for the value of the variable:
lazy var s : String = {
// ... do stuff here
return result
}()

How does Objective C deals with primitive __block variables on stack when block is copied?

I have the following code under ARC:
-(void) foo {
__block int spam = 42;
self.myProperty = ^{
spam++;
}
self.myProperty(); // Increment first time
}
-(void) bar {
self.myProperty(); // Increment second time
}
When "Increment first time" is called, ObjC uses pointer to spam (which resides on stack) to increment it, right?
After it, foo stack is thrown out, so pointer is not valid anymore.
What will bar do? What should happen when I call it?
Everything is clear about objects, since they are created on heap and block copying (which takes place in the moment of property assignment) leads to retain call. But what is about auto vars?
I can use debugger to find the answer, but I want to fully understand it: which part of Objc/clang specification covers that?
Update: A used "&" to get address of my variable and found that address get changed in the moment I assign block to my property (actually at the moment when block is copied). I believe that is the moment from my variable was moved from stack to heap.
-(void) foo {
__block int spam = 42;
int* addrOfSpam = &spam;
*addrOfSpam = 43; // OK, spam = 43 now
self.myProperty = ^{ // The moment when spam is moved from stack to heap
spam++;
};
*addrOfSpam = 44; // Fail, spam not changed and 'addrOfSpam' points to nowhere
spam++; // Spam looks like auto/stack var here, BUT IT IS NOT!
// It is on heap now, and "spam" is changed by compiler to:
// *(newAddressOfSpamInHeap_OnlyCompilerKnowsWhere)++;
}
The salient passage in the doc is here. (boldface added by me)
__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.
The block qualifier places the variable in a scope that will persist at least as long as the block that refers to it. So the first and second invocations of the block are identical with respect to the variable. After the second call, spam should equal 44.
First of all, __block is a storage qualifier for variables, and it the same way for all types of variables. Whether it's a variable of primitive type, pointer-to-object type, or whatever (by the way, a variable cannot have "object type"); doesn't matter. Variables of all types normally reside on the stack if they are local variables of a function. Referring to a local variable of pointer-to-object type after its scope has exited equally results in undefined behavior.
About your question, the answer is that __block variables are not only stored on the stack. They can also be stored on the heap. How it works is an implementation detail but it's guaranteed by the specification to be valid to be used in all the blocks that capture it.
If you want to know how it is actually implemented, you can read Clang's Block implementation specification (although I think there are some typos). Essentially, when you have a __block variable, you actually have a data structure, where the variable is a field. And the data structure also has a pointer to keep track of where the current version of itself is. Accesses to the variable are implicitly translated by the compiler to access it through these levels of indirection.
Just like with blocks, this data structure starts out on the stack for optimization, but can be "moved" to the heap (it gets moved the first time any block that captures it gets moved to the heap, because that's when its lifetime might need to exceed the scope it was created in). When it's "moved" to the heap, the pointer that says where it is is updated, so that people will know to use the new copy. This data structure, when in the heap, is memory-managed by a system of reference counting.
Blocks that capture __block variables have a copy of the "current version" pointer, which is updated when the data structure is moved, so they know where to access the variable both before and after the move.
About your tests, you have to be really careful about taking the address of a __block variable, because the location of the variable moves over its lifetime! (something that doesn't usually happen in C).
When you first take the address of spam, it is still on the stack, so you have the address of the stack version of it. spam is captured in a block which is then assigned to the property myProperty whose setter copies the block, moving it to the heap and also moving spam to the heap. addrOfSpam still points to the stack version of the variable which is no longer the version being used; using it to change the integer is changing the wrong version of the variable, because everyone is using the heap copy now.

How to check if a CGSize is initialized (or if its value is different from "nil") [duplicate]

This question already has answers here:
Sending nil to CGPoint type parameter
(2 answers)
Closed 9 years ago.
I have a CGSize property in a class and I need to check if it has been initialized. I know that a CGSize isn't a object, but generally speaking, is the same idea of checking if an object is different from nil. How to do that?
You can compare it to CGSizeZero or an arbitrary size that you consider invalid.
if (!CGSizeEqualToSize(CGSizeZero, mySize)) {
// do something
}
It depends on what you mean by "in a class". If this is an instance variable, your problems are over, because you are guaranteed that an instance variable will be auto initialized to some form of zero (i.e. CGSizeZero). But if you just mean "in my code somewhere", e.g. an automatic variable, then there is no such test; it is entirely up to you to initialize before use, and until you do, the value could be anything at all (sorry, but that's how C works).
On the whole, your question is itself a "bad smell". If it matters to you at some point in your code whether this value has been initialized, then you are doing it wrong. It's your value; it was up to you to initialize it (e.g. when your overall object was initialized). Or, if for some reason you need to know whether your setter has ever been called, then you need to add a boolean to your setter that tells whether it has ever been called.
CGSize is a C struct. With few exceptions (when used as an iVar), there is no guarantee for its initialized value. It could be anything, especially when created on the stack.
Thus, you are responsible for initializing it properly, and since "zeros" are valid values, there is no guaranteed way to tell if it was set to "zero" on purpose, or it has been uninitialized.

Returning block that lives on the local stack

The clang analyzer can check for returning stack-based memory.
dispatch_block_t getPrintBlock (const char *msg) {
return ^{
printf("%s", msg);
};
}
raises this error: returning block that lives on the local stack
What does this error mean?
The error means you are returning a value which will be invalid after the method returns. This is not just an issue with blocks, consider:
- (int *) badMethod
{
int aLocalIntVariable;
return &aLocalIntVariable; // return a reference to aLocalIntVariable, but that variable is about to die...
}
Local variables are created when a method is entered, the place where they live is called the "stack". When a method returns those local variables are destroyed. You can return a value in such a variable, but you cannot return a reference to the variable itself - it will be invalid. You can pass a reference to a local variable to a method you call, as your local variable still exist in that case.
In your case you have created a block. Objective-C happens to create block values on the stack, i.e. effectively in an anonymous local variable, and refer to them using a reference. You can pass such a reference to a method you call, but you cannot return it - that anonymous local variable is destroyed just like any other.
However Objective-C provides you two ways to create a copy of a block value as an object, which lives on the "heap", and which will outlive its creator. First there is Block_copy which is a function:
<reference to heap allocated block> = Block_copy(<reference to stack allocated block>);
This is the original way to do this and is supported every - including in pure C code, blocks are part of C and not just Objective-C. The second way pretends the block is an object already and allows you to send the standard copy message:
<reference to heap allocated block> = [<reference to stack allocated block> copy];
If you are primarily an Objective-C person this second method probably feels more comfortable, but does blur the issue of why it is needed in the first place.
ARC helps here, in automating memory management it will automatically copy blocks from the stack to the heap (at least in current compilers, it may not work properly in earlier compilers) and so the programmer can ignore what is really an implementation detail.
Addendum: ARC
The last paragraph above was queried by #newacct and a long Q&A comment exchange resulted. In an attempt to make the information in that easier to follow we have both removed our comments and I have consolidated the information here as an addendum.
In understanding how ARC handles blocks two documents are useful:
Objective-C Automatic Reference Counting, in particular sections 3 (blocks are retainable object pointers), 3.2.3 (retainable object types are valid across return boundaries) and 7.5 (rules for when blocks are copied).
Transitioning to ARC Release Notes, in particular the FAQ item "How do blocks work in ARC?"
From these it can be determined that most of the time ARC will handle all copying of blocks from the stack to heap as part of its management of all object types.
The second reference highlights one case, that at least at the time the document was written, was not handled automatically. That case is where a stack allocated block is passed to a method parameter of type id, e.g. something like:
- (void) takeBlockWithTypeLoss:(id)block { ... }
[obj takeBlockWithTypeLoss:^{ ... }];
In such cases, at the time the document was written, ARC did not copy the block. If the called method then performs an operation which retains the passed block a problem occurs as the retain value is not on the heap. (Note that the block needs to be stack allocated for a problem to occur. Literal blocks which do not reference variables in their environment are statically allocated, also a literal block which is first stored in a local variable with default strong ownership and then passed to the method will be copied.)
This case is an example of type loss, a value known to be a block type is passed as id loosing type information. The compiler can always determine such points, so why does (or did..) ARC not copy the block? The answer given in the past is simply one of efficiency, the copy may not be required and lots of unneeded copies is a performance hit.
However the current compiler (Xcode 4.6.1) appears to handle this one remaining case, at the point of type loss a block is copied to the heap. If anyone can show this is now documented (or you are confident that your compiler handles this case e.g. by coding a check) then it would appear Block_copy() (or [block copy]) can be relegated to history, if not then when type loss occurs it should be used.
Addendum: June 2013
As revealed by this question there is a case that Xcode 4.6.3/Clang 4.2 does not handle. When a block is passed as one of the variable arguments to a variadic method then the compiler does not automatically promote a stack block to the heap. This is a subcase of type loss mentioned above.
So there is a case current compilers do not handle, which suggests a reason why the compiler supporting more than the specification is undocumented - that support is incomplete (though these is no theoretical reason that it needs to be).
So as before, if there is type loss then the compiler may not handle block promotion automatically (but this can be tested for if so desired), cases not involving type loss are handled automatically as per the specification.
(BTW. The older question mentioned in a comment to the question above is now one of the cases covered by the specification and handled correctly by the compiler.)
You need to make a copy of the block to move it to the heap.
i.e. something like:
dispatch_block_t createPrintBlock (const char *msg) {
return Block_copy(^{
printf("%s", msg);
}) ;
}

What is the -> operator doing in -copyWithZone:? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Arrow operator (->) usage in C
Dot (“.”) operator and arrow (“->”) operator use in C vs. Objective-C
I'm a newbie looking at a freeware/open-source program last updated in 2008, and I don't recognize the -> in the following notation:
- (id)copyWithZone:(NSZone *)zone
{
GFIPGeniusItem * newItem = [[[self class] allocWithZone:zone] init];
newItem->_stringValue = [_stringValue copy];
newItem->_imageURL = [_imageURL copy];
newItem->_webResourceURL = [_webResourceURL copy];
newItem->_speakableStringValue = [_speakableStringValue copy];
newItem->_soundURL = [_soundURL copy];
return newItem;
}
I'm assuming it's allowing some sort of shortcut, but I'd love to specifically what it does.
It's a way to directly access an instance variable within an ObjC object from outside that object. (The syntax and -> is borrowed from C structs, behaving as if the reference were a pointer-to-structure).
This access mechanism is almost vestigial at this point, and very uncommonly seen in modern ObjC code, because good encapsulation requires the use of accessors and properties, not touching instance variables directly. It's legitimate in some very special cases, though, and this is one of them:
When copying an object, you want to get a resulting copy that matches exactly the state of the current self. The cleanest way of achieving this is often to set the copy's ivars explicitly, to prevent any side-effects that the init overloads or accessors might cause. It's "safe" because the code doing it is still located within the class that's in question, so if you needed to change or add ivars, you could update this code as well with the knowledge of anything else that might require.
Doing this from outside the class in question is bad form, and there's no good reason to do it.
In Objective-C you have some kind of two variable type accessors. The one everybody should know is the "." one (e.g. Class.variable). This type calls either the appropriate getter or setter.
Now, the other type - the one you asked for - is for in-class usage. Obviously, as the getter or setter gets called automatically with the "." notation you need a way to set the variable without a setter (calling the setter in the setter itself results in an endless loop). Therefore, this "->" notation is used -> simply, it is the direct-access mode.
Usually, Objective-C the variable name for both notations is the same but some prefer to have the in-class notation variable name beginning with "_". This is achieved by editing the #synthesize variable line to #synthesize variable = _variable.
That's a pointer indirection operator. a->b means the same thing as (*a).b (where the . is the structure member access operator, not Objective-C's property dot syntax).
When you say:
newItem->_stringValue
you're directly accessing the _stringValue instance variable of the object to which newItem points.
The -> operator is very common in C++, but not so much in Objective-C.
In Objective C, like in C++, the p->m notation is equivalent to (*p).m This is, the dereference of the pointer to the base type followed by a call to the corresponding method or property.
So in your case, using the other notation it would look like this:
(*newItem)._stringValue = [_stringValue copy];
(It's more common to use the -> operator)