2

I can't reproduce some bug that happens sometimes. This is a report:

Exception Type:  EXC_CRASH (SIGSEGV)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Triggered by Thread:  1

Thread 0:
0   libobjc.A.dylib                 0x3b4b97fa objc_release + 10
1   MyApp                           0x00173610 -[AFHTTPRequestOperation error] (AFHTTPRequestOperation.m:136)
2   MyApp                           0x001460ea -[RKObjectRequestOperationLogger HTTPOperationDidFinish:] (RKObjectRequestOperation.m:209)
3   CoreFoundation                  0x31121e6e __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 10
4   CoreFoundation                  0x31095aac _CFXNotificationPost + 1716
5   Foundation                      0x31a7bec0 -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
6   Foundation                      0x31a807c2 -[NSNotificationCenter postNotificationName:object:] + 26
7   MyApp                           0x0017e44e __34-[AFURLConnectionOperation finish]_block_invoke (AFURLConnectionOperation.m:558)
8   libdispatch.dylib               0x3b9a10c0 _dispatch_call_block_and_release + 8
9   libdispatch.dylib               0x3b9a10ac _dispatch_client_callout + 20
10  libdispatch.dylib               0x3b9a39a4 _dispatch_main_queue_callback_4CF + 264
11  CoreFoundation                  0x3112a5ac __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 4
12  CoreFoundation                  0x31128e78 __CFRunLoopRun + 1304
13  CoreFoundation                  0x3109346c CFRunLoopRunSpecific + 520
14  CoreFoundation                  0x3109324e CFRunLoopRunInMode + 102
15  GraphicsServices                0x35dcd2e6 GSEventRunModal + 134
16  UIKit                           0x33948840 UIApplicationMain + 1132
17  MyApp                           0x00014d54 main (main.m:16)
18  libdyld.dylib                   0x3b9b5ab4 start + 0

Thread 1 Crashed:
0   libsystem_kernel.dylib          0x3ba59838 kevent64 + 24
1   libdispatch.dylib               0x3b9a80d0 _dispatch_mgr_invoke + 228
2   libdispatch.dylib               0x3b9a261e _dispatch_mgr_thread + 34

What can i understand from such a record? Who can be a culprit? AFHTTPRequestOperation.m:136 don't looks that can to cause the crash

135:    - (NSError *)error {
136:        if (!self.HTTPError && self.response) {
137:            if (![self hasAcceptableStatusCode] || ![self hasAcceptableContentType]) {

so from where objc_release can come? Does objc_release means that ARC tries to release something from memory? In what period of time (place in code) it can be happened?

providing code of AFURLConnectionOperation.m :

    - (void)finish {
        self.state = AFOperationFinishedState;

        dispatch_async(dispatch_get_main_queue(), ^{
558:            [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidFinishNotification object:self];
        });
    }
adsurbum
  • 3,107
  • 3
  • 22
  • 27
  • You should post code to the block that is invoked here: __34-[AFURLConnectionOperation finish]_block_invoke (AFURLConnectionOperation.m:558) ... blocks cause the objects referenced in the block to be retained. – stevesliva Mar 25 '14 at 16:38
  • I've added. dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidFinishNotification object:self]; }); – adsurbum Mar 25 '14 at 17:46

1 Answers1

2

Try using the weakSelf code pattern with the block. A weak rather than a strong reference within the block will avoid the release, hopefully.

See the answers here: What is the proper way to avoid Retain Cycle while using blocks

I actually like the 2nd most popular answer for async. And I really really like it because you have this method called "finish" -- if you happen to make self go away simultaneous with the block being executed, perhaps you get this error.

Hope that works for you.

Community
  • 1
  • 1
stevesliva
  • 5,351
  • 1
  • 16
  • 39
  • Using the `weakSelf` pattern certainly won't help avoiding the release. – Kamchatka Oct 01 '14 at 20:10
  • @Kamchatka - the release in the stack trace here is the release of the block itself. When the block's released, there's a seg fault. I absolutely believe that avoiding `self` being retained by a block created in an instance method named `finish` is important if the asynchronous invocation of that block causes a seg fault. Probably not clear in my answer, though about what exactly is being avoided. Would be better to figure out where he tramples on self before the block is executed, perhaps. – stevesliva Oct 02 '14 at 00:28
  • Making it weak would make `postNotificationName:object:` post with `nil` for the `object` parameter. You would need to hold a strong reference to `self` in the block, so do the weakSelf/strongSelf dance. Btw how can you see this release is the block's release? – Kamchatka Oct 02 '14 at 06:58
  • Yeah, I think that's desired if the issue truly is with self having become a bogus pointer. `_dispatch_call_block_and_release` in the stack trace... which is what I was focusing on when I nattered on about avoiding the release, but you're right, it avoids invoking the block entirely, and there'd be no notification posted. Presumably the app doesn't care any longer if `self` is a garbage pointer at that point in time. I am admittedly unsure exactly how there'd be the segfault if self is strongly retained by the block... it should have a nonzero retain count, so something else is going on. – stevesliva Oct 03 '14 at 04:57
  • 1
    The issue is likely not in that piece of code (that's AFNetworking's code) but probably there where the operation is created. – Kamchatka Oct 03 '14 at 07:59