1

I've got a UIViewController with UICollectionView, implementing its delegate and dataSource. In 95% everything is working ok, but sometimes I get a crash (log, code etc below). I think it happens when successBlock of myOperation is executed in same moment as the controller gets deallocated (but I'm not sure).

Considering other question from SOF I assume myCollectionView == nil, however the delegate is still pointing somewhere (shouldn't it be changed, it's just assign property as far as I see). I have no idea how to fix such kind of issue, does anyone have any idea?

Crash log:

MyCollectionViewController.m line 0
__destroy_helper_block_
Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x0000000a

Call stack:

libobjc.A.dylib 
objc_msgSend + 5
retain

UIKit   
-[UICollectionViewController collectionView] + 54

MyAppName   
MyCollectionViewController.m line 30
-[MyCollectionViewController dealloc]

MyAppName   
MyCollectionViewController.m line 0
__destroy_helper_block_

libsystem_blocks.dylib  
_Block_release + 216

MyAppName   
MyDownloaderController.m line 0
__destroy_helper_block_75

libsystem_blocks.dylib  
_Block_release + 216

MyAppName   
MyOperation.m line 0
__destroy_helper_block_19

libsystem_blocks.dylib  
_Block_release + 216

MyAppName   
MyOperation.m line 0
__destroy_helper_block_112

libsystem_blocks.dylib  
_Block_release + 216

UIKit   
UIApplicationMain + 1136

MyAppName
main.m line 15
main

Where lines around 30 in MyCollectionViewController:

- (void)dealloc {
    if ([self isViewLoaded] && self.collectionView) { // line 30
        self.collectionView.delegate = nil;
        self.collectionView.dataSource = nil;
        self.collectionView = nil;
    }
}

My successBlock:

MySuccessHandler successBlock = ^(UIImage *image) {
    if (weakCell) {
        [weakCell.pageImageView setImage:image];
    }
};
Community
  • 1
  • 1
Nat
  • 12,032
  • 9
  • 56
  • 103
  • So you are using both ARC and `dealloc`? – trojanfoe May 20 '14 at 10:03
  • 1
    You can override the `dealloc` method while using ARC, you just can't call `[super dealloc];` – Guy Kogus May 20 '14 at 10:05
  • Sure. But why in *this* case? – trojanfoe May 20 '14 at 10:05
  • @Vive if you're using a straightforward view controller with a collection view, you don't need any of that code in the `dealloc` method, it will all happen automatically. – Guy Kogus May 20 '14 at 10:06
  • it's perfectly valid to use `-dealloc` under ARC! `-[super dealloc]` gets called automatically by ARC at the end of the method, so you must not call it explicitely. – Michael May 20 '14 at 10:07
  • 1
    Removing the `dealloc` code will solve the immediate issue as `self.collectionView` is *dangling*. However the important thing to learn is *why* is it dangling? – trojanfoe May 20 '14 at 10:07
  • I don't remember what was the problem, however I needed to set `collectionView` `delegate` and `datasource` to `nil` because it was crashing otherwise. I wonder why is it corrupted? – Nat May 20 '14 at 10:11
  • @Vive Yeah looks like something nasty is happening elsewhere. Remove the `dealloc` code and get it to crash again and provide the new stacktrace and then show `@property` declarations in your question. – trojanfoe May 20 '14 at 10:12
  • Somewhere there must be an unsafe_unretained variable or property (instead of weak) or a nonatomic strong variable or property that is accessed from multiple threads (multiple readers would be okay, but multiple writers or one writer and some readers are unsafe) – Michael May 20 '14 at 10:13
  • 2
    @Vive UICollectionViews delegate and dataSource properties are not weak, but unsafe_unretained. So it is true that you have to unset the delegate and dataSource properties in the -dealloc handler. Unfortunately, the UIKit makes very little use of weak references. – Michael May 20 '14 at 10:16
  • @Michael This is a snippet from UIKit->UICollectionView.h `@property (nonatomic, assign) id delegate;`. The only thing I've written is that it is assign, so I suppose it's a correct statement. I'm used to set delegates to nil because in Apple documentation they state that UIWebView and MKMapView delegates should be nilled before releasing (so dealloc in case of property/ivar)- so for sake I nil it with all Apple-stuff. I'm debugging now to find the old problem without this dealloc method as @trojanfoe wrote. – Nat May 20 '14 at 10:30
  • @trojanfoe It will take a while to debug it and bring any further logs however as far as i remember, I've enabled zombies in instruments and found out, that reference count on collectionView dropped to -1, what caused a crash. – Nat May 20 '14 at 10:39

0 Answers0