0

I believe I was following the rules but still a problem exists

My class init includes a block like this:

HTTPChunkReceiveBlock chunkBlock =  ^(id connection, NSData *data) {
    NSLog(@"Hi there!!");
};

and I am passing this block into an HttpConn obj which my class holds:

operation_ = [[HttpClient sharedClient] performChunkedRequest:url 
                                                 chunkHandler:chunkBlock];

Now for the problem: my object is never deallocated!!

The problem seems to be caused because the HttpConn is keeping a pointer to the block, but I want to mention two points:

  1. The block is not referring to self!
  2. The HttpConn class is keeping a copy of the block, like this:

    chunkBlock_ = [chunkBlock copy];

Any explanation would be greatly appreciated!

EDIT

Extra info: I have verified that if I'm freeing operation_ then my object is deallocated fine:

reader.operation_ = nil;
reader = nil; //previous line allows 'dealloc' to be called

Now repeating the question: operation did not get a pointer of reader's self, it only holds a copy of the block which do not refer to self!

René Hoffmann
  • 2,766
  • 2
  • 20
  • 43
ishahak
  • 6,585
  • 5
  • 38
  • 56
  • 2
    How do you know the block is the culprit? Have you actually verified using Instruments? I very much doubt it. – DarkDust Mar 10 '14 at 09:55
  • is your class acting as delegate, that would be a typical retain cause – Volker Mar 10 '14 at 09:57
  • To avoid a memory leak, you must always balance a Block_copy() with Block_release(). – Himanshu Joshi Mar 10 '14 at 09:58
  • @Volker O_o Delegates are usually defined as `assign`, not `retain` to not create a cycle. But you're right, it might be something to check. – DarkDust Mar 10 '14 at 10:01
  • First of all, I'm amazed by the time it took you guys to respond, well appreciated!! Unfortunately I'm failing to use Instruments because it is causing me a segmentation fault in an unrelated, different place. This class is not used as a delegate. IMHO in ARC I shouldn't call Block_release. I have verified that if I am sending a 'nil' as the block, my object is deallocated ok – ishahak Mar 10 '14 at 10:58
  • 1
    @ishahak: Alright, so the block _is_ the culprit. Does the block really look like the above, just an `NSLog`? If not, please post the real block. – DarkDust Mar 10 '14 at 11:49
  • Hi @DarkDust, I have nothing to hide, it is indeed only this :) (there was some real code but it was removed while trying to eliminate the root cause) – ishahak Mar 10 '14 at 12:14
  • 1
    Hm, have you redefined `NSLog` to be a macro for better logging? (Command-click on NSLog to see its definition.) Other than that I fail to see how _anything_ might get captured by your block. – DarkDust Mar 10 '14 at 12:22

1 Answers1

1

Ok, I will answer my own question so that others do not fall into the same problem. @DarkDust was actually correct. there was a tiny line which I was completely ignoring:

**retriesNumber++;**

It looks like an innocent sentence, but because retriesNumber is a member of the class, it is actually meaning

(INVISIBLE strong pointer to self)->retriesNumber

so the solution was to declare it as a property (versus a member ivar) so that we can use self to access it, and then write:

pSelf->retriesNumber++;

Thank you guys for your quick support, and I hope others will learn from it too!

ishahak
  • 6,585
  • 5
  • 38
  • 56
  • 1
    The `foo->bar` syntax actually access the _instance variable_ `bar` on the object pointed to by `foo`, so you don't need a property here. The important point is to use a [weak reference to `self`](http://stackoverflow.com/a/7854315/400056). – DarkDust Mar 11 '14 at 08:54
  • Hi @DarkDust, I have fixed my answer to make it clearer, saying INVISIBLE. The point here is that self is not appearing when referring to ivars. We must turn it into a property so that the weak self can be used – ishahak Mar 11 '14 at 12:43
  • 1
    I was talking about `pSelf->retriesNumber++;`, this isn't accessing a property, it's accessing an instance variable. – DarkDust Mar 11 '14 at 12:54
  • If I'm not wrong, the compiler will complain when using -> over a weak pointer which might become nil at some point. When using a property, you are sending a message, which is a safe operation – ishahak Mar 14 '14 at 02:41