didReceiveMemoryWarning and re-built instance variable equality checking

I'm going through my iOS app, using "Simulate Memory Warning" as my hammer of justice, and it's causing some unexpected problems (naturally). But this is one problem that has me stumped: objects are seemingly no longer equal.

Say my view controller (we'll name it VCBob) has…

  • two separate custom UIViews as subviews (let's name those views viewA and viewB)
    • each with their own UICollectionView exposed as the property collectionView (these UICollectionViews use VCBob as their delegates)
  • a UIButton that, when pressed, pushes some other view controller (an otherwise insignificant one) on to the stack

So I tap on the UIButton and here comes the insignificant view controller. I fire off the "Simulate Memory Warning" option, and VCBob is programmed to ditch viewA and viewB inside of -didReceiveMemoryWarning, since they are being totally recreated and re-inserted into the view hierarchy on viewWillAppear (so long as they're nil at the time of viewWillAppear). Here's that implementation in VCBob:

- (void)didReceiveMemoryWarning {
    BOOL hasSuperview = self.view.superview != nil;
    [super didReceiveMemoryWarning];

    if (!hasSuperview) {
        _viewA = nil;
        _viewB = nil;
    }
}

I then tap the back button in the navigation bar, and VCBob comes back into play. The two custom UIViews are still there, and their respective UICollectionViews are loaded with content. When I tap on one of the UICollectionViewCells in either of the collection views, the -collectionView:didSelectItemAtIndexPath: method gets called on VCBob; so far, so good. That implementation looks like this.

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    if (collectionView == self.viewA.collectionView) {
        NSLog(@"Do something here!");
    } else if (collectionView == self.viewB.collectionView) {
        NSLog(@"Do something else here!");
    }
}

The problem is nothing happens — nothing gets logged. Both of those if conditions evaluate to false. Why is that? I kinda seem to think I might be doing bad things in didReceiveMemoryWarning. Should I not be disposing of views there?

Answers


If _viewA is in a view hierarchy, it is retained by its superview, so doing _viewA = nil will not release it, and it will still be there when the viewWillAppear method gets fired.

Then, in your viewWillAppear you are adding a "duplicate" of your viewA, with its own collectionView inside, placed just over the original one: you see one view, but in truth they are two views overlapped.

So, you should just add a removeFromSuperview call in your didReceiveMemoryWarning method to get rid of this

The same happens for viewB.


Need Your Help

How to convert MAC string to colon-separated string

java string-conversion

I have csv file with 200k rows and 3 types of MAC address defined as:

NSSplitViewItem does not display like it designed in IB

objective-c xcode cocoa interface-builder nssplitview

I created a new empty Xcode project. And just added a NSSplitViewController to storyboard like below.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.