1
__block NSString *x = @"123"; //  x lives in block storage
void (^printXAndY)(NSString*) = ^(NSString *y) {
    x = [x stringByAppendingString:y];
    printf("%@ %@\n", x, y);
};
printXAndY(@"456");

Apple docs says:

The __block Storage Type You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier.

If the x is mutable, isn't this x = [x stringByAppendingString:y]; wrong? and can cause memory leaks?

S.J
  • 3,063
  • 3
  • 33
  • 66
  • 1
    Nothing is allocated, so what can leak? – trojanfoe Oct 01 '13 at 09:54
  • @trojanfoe If x is string? – S.J Oct 01 '13 at 10:02
  • @trojanfoe I update the code in question. Please view. – S.J Oct 01 '13 at 10:06
  • @trojanfoe its nsstring, please view the code I updated it. – S.J Oct 01 '13 at 10:13
  • Not sure I can see a leak there. I assume you are using ARC? – trojanfoe Oct 01 '13 at 10:17
  • @trojanfoe x is mutable and assigning the new value will cause the leak. – S.J Oct 01 '13 at 10:34
  • @trojanfoe apple docs says "The __block Storage Type You can specify that an imported variable be mutable—that is, read-write— by applying the __block storage type modifier.". Will it make any variable mutable? even int? – S.J Oct 01 '13 at 10:36
  • Yes. However you need to consider the type of the variable; for example if you have a `NSMutableString` you won't need the `__block` specifier as the variable in this case is an object pointer and the object will still be mutable (the block will copy the pointer). In the case of `int` you will need the `__block` specifier. – trojanfoe Oct 01 '13 at 10:43
  • The compiler will tell you anyway: `error: variable is not assignable (missing __block type specifier)` – trojanfoe Oct 01 '13 at 10:46
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/38462/discussion-between-s-j-and-trojanfoe) – S.J Oct 02 '13 at 05:32

1 Answers1

3

First, you are confusing two completely unrelated things: 1) the variable being assignable (i.e. non-const), and 2) if the variable is of object pointer type, the object it points to being "mutable".

Non-__block local variables are const inside a block, which means you can't do x = something. Making the variable __block allows you to do x = something inside the block (regardless of the type of x). When x is a pointer variable, assignment to it makes it point to something else.

So-called "mutating" a "mutable" object just means you can call a method on it that somehow changes the "contents" of the object. It does not involve assigning to any pointers that may point to this object.


As to your second question, memory leaks, no, there shouldn't be any memory leaks. First of all, if you're using ARC, it's obvious that there are no leaks. Even if you are using MRC, there are no leaks. In fact, if this is MRC, none of the object pointers in this code has been retained by your function (they are not the result of retain, alloc, new, copy, etc.), so there cannot possibly be a leak.

newacct
  • 119,665
  • 29
  • 163
  • 224