0

I have a very strange problem and I cannot find a solution. In one of my apps I need to create a UISearchDisplayController programatically. I am creating it in a subclass of UITableViewController. And I run into a very simple problem - my search display controller either gets released immediately OR it causes the retain cycle and prevents its contents controller from getting released.

In my viewDidLoad method I instantiate my UISearchDisplayController with this code:

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
sC = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchDisplayController.searchResultsDelegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.searchDisplayController.delegate = self;

If sC is defined as a property or instance variable in my view controller, search controller works, but it prevents dealloc method of my view controller from being called. If, however, sC is defined as the variable only within viewDidLoad method, my view controller gets deallocated fine, but self.searchDisplayController becomes nil almost instantly and search doesn't work.

Does anyone know how to solve this? I have already tried overriding the searchDisplayController property - it doesn't help.

I should probably mention that I am using ARC. Also, when I say that "dealloc isn't called" I mean that I have an NSLog statement there which doesn't get printed.

Update

As some users suggested that there is already an answer and that simply overriding the searchDisplayController property should work I post below what I did (which didn't work).

I added a property to my subclass of UITableViewController:

@property (nonatomic,strong) UISearchDisplayController *searchDisplayController;

In my viewDidLoad I initialised my search controller:

UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
self.searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchDisplayController.searchResultsDelegate = self;
self.searchDisplayController.searchResultsDataSource = self;
self.searchDisplayController.delegate = self;

In the dealloc method of my view controller I have:

- (void)dealloc
{
    NSLog(@"dealloc");
    self.searchDisplayController = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Line "dealloc" doesn't get printed and if I profile with instruments my view controller is not getting released.

I have also tried adding other properties with different name - it still doesn't get deallocated.

Andriy Gordiychuk
  • 6,163
  • 1
  • 24
  • 59
  • possible duplicate of [UIViewController does not retain its programmatically-created UISearchDisplayController](http://stackoverflow.com/questions/7679501/uiviewcontroller-does-not-retain-its-programmatically-created-uisearchdisplaycon) – dopcn Jun 25 '15 at 01:38
  • @dopcn No it is not, because as I said in the question, I know how to retain it. The problem is that if I do I cannot release it. Read more carefully – Andriy Gordiychuk Jun 25 '15 at 01:39

2 Answers2

0

haha have you ever go into that question I provided. So summary of that question's accepted answer:

  1. use a property to hold your UISearchDisplayController
  2. when the holder viewController is dealloc nil it out

    - (void)dealloc {
         self.searchDisplayController = nil;
    }
    
  3. don't use UIViewController's default property searchDisplayController it's broken

dopcn
  • 4,218
  • 3
  • 23
  • 32
  • Yes I did and I have indicated in my question "Does anyone know how to solve this? I have already tried overriding the searchDisplayController property - it doesn't help.". Dealloc is still not getting called. Tested on iOS 8 and iOS 9 – Andriy Gordiychuk Jun 25 '15 at 01:47
0

Ok, I have figured it out. In order for dealloc to be called on the view controller which initialises the UISearchDisplayController I had to do this:

At the top of .m file add the following:

static UISearchDisplayController *sC;

Then in viewDidLoad initialise the search controller like this:

    if (sC==nil) {
        UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
        sC = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
    }
    self.searchDisplayController.searchResultsDelegate = self;
    self.searchDisplayController.searchResultsDataSource = self;
    self.searchDisplayController.delegate = self;

And then in the dealloc method do the following:

- (void)dealloc
{
    sC = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

And now it all works great. Search controller is working fine and everything gets deallocated as it should :)

Andriy Gordiychuk
  • 6,163
  • 1
  • 24
  • 59
  • This is an old answer, but I have to say, you didn't use `sC` variable at all. So this is nonsense. – kientux Jul 14 '16 at 08:25