6

If I try to access an "object variable" with a __block storage type:

@interface {
__block float x;
}

in a block:

@implementation ... {
...
-(void) func: {
   ^(...) {
      x = 0;
   }
} 

I get a "retain cycle" warning, unless I create a __block reference to self and use it like:

-(void) func: {
   __block id s = self;
   ^(...) {
      s->x = 0;
   }
} 

Why is it possible to declare a variable "__block" in an interface?

Rudi Rüssel
  • 439
  • 4
  • 13
  • Retain cycle warning for a non-object type? Clang, you're screwed. –  Oct 16 '12 at 14:03
  • An unboxed/boxed var is not accessible within a block without a __block type. This is the default behavior for LLVM 4.1. – Rudi Rüssel Oct 16 '12 at 14:22
  • 4
    @H2CO3: Not exactly. Accessing an instance variable means going through the object, which has to be retained. – Jesper Oct 16 '12 at 15:20
  • 1
    Attempting a short answer, which will be demoted to a comment anyway, it's allowed because they'd have to write a lot of code to demarcate where a storage class modifier may be used. I think they just didn't think about it. It's not particularly useful and it's hard to write code that doesn't accidentally retain the object in a cycle too. `__block` is meant for local variables. Every other use is a bug farm. – Jesper Oct 16 '12 at 15:22
  • @Jesper yes, that's right, but it's still silly. –  Oct 16 '12 at 15:23
  • 5
    @H2CO3: If I had a nickle for every time I saw something possible but silly in C, I'd have gotten very rich off of [Duff's device](http://en.wikipedia.org/wiki/Duff%27s_device) alone. – Jesper Oct 16 '12 at 15:25
  • @Jesper ehm, that's for optimization, right? But this is just bad compiler design. They're not even close. –  Oct 16 '12 at 15:27
  • 1
    @Jesper Similar thing with ARC. It's supposed to be 'automatic', but there so many exceptions in automatic memory management, blocks and whatever, that in the end writing ARC code is less clean and less concise (along with the I-don't-see-why-prefixed-with-ugly-double-underscore storage specifiers). –  Oct 16 '12 at 15:28
  • With regards to bad compiler design, see my previous comment. Also, the fact that Duff's device is even possible in C testifies to how hard it must be to perform static analysis on it. – Jesper Oct 16 '12 at 15:28
  • 1
    @Jesper Yes, but there's an alternative for static analysis: thinking. –  Oct 16 '12 at 15:29
  • @Jesper (Duff and/or the writers of the Standard should still have been beaten anyway...) –  Oct 16 '12 at 15:32
  • @H2CO3: If that is with regards to ARC, that means you'd rather spend time thinking about memory management than about what your code does. ARC is far from perfect, but I'd take it any day above manual memory management. – Jesper Oct 16 '12 at 15:34
  • @Jesper If one needs to think a lot about memory management, then he doesn't quite know/understand it well enough. I think ARC would be very good if it was simple. But apparently it couldn't be kept simple. As I just stated, while it was supposed to facilitate programmers' life, it gradually became a mess as Objective-C evolved. And finally we have to concentrate on more things, corner cases and stuff like that than we had to do so using MRC. –  Oct 16 '12 at 15:37
  • 5
    ARC is actually quite simple, it is just very pedantic. The border between blocks and self is one that is a **massive** source of bugs in MRR code. I have quite a bit of experience moving large codebases to ARC. Total PITA, but the end result is a dramatic drop in complexity and crashes. – bbum Oct 16 '12 at 17:20
  • 2
    @H2CO3: Let me point out that bbum is on the Apple Objective-C team and probably knows a little about what sort of thing happens even to very experienced Objective-C programmers. – Jesper Oct 18 '12 at 07:51
  • 1
    @Jesper Shame on him. My opinion doesn't change about ARC, neither am I afraid of bbum. –  Oct 18 '12 at 09:53
  • @H2CO3: To each their own opinion. I didn't appeal to authority, I appealed to experience. – Jesper Oct 18 '12 at 09:58
  • @Jesper Sorry in this case, for me it seemed so. –  Oct 18 '12 at 11:13
  • Recap: using "__block" in an interface is possible but ineffectual? – Rudi Rüssel Oct 18 '12 at 13:19
  • Could this be related? http://stackoverflow.com/questions/8011581/arc-ivars-in-blocks-and-reference-cycles-via-captured-self – nhisyam Mar 06 '13 at 07:12

1 Answers1

0

__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. see

Community
  • 1
  • 1