1

У меня есть небольшое недоразумение относительно ARC. Я создаю новый UIViewController, используя следующий код:ARC и ViewControllers

CGRect screenRect = [[UIScreen mainScreen] bounds]; 

    LocationProfileView *locationProfile = [[LocationProfileView alloc] initWithLocation:l]; 

    locationProfile.view.frame = CGRectMake(0, screenRect.size.height, screenRect.size.width, 400); 
    [appDelegate.window addSubview:locationProfile.view]; 

    [UIView animateWithDuration:.25 animations:^{ 
     locationProfile.view.frame = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height); 
    }]; 

В своей UIView я поставил кнопку, которая удаляет вид с экрана. Проблема заключается в том, что locationProfile получает освобождение сразу после его добавления на экран, поэтому каждый раз, когда я пытаюсь нажать кнопку «Закрыть» (которая вызывает метод в классе LocationProfileView), мое приложение выйдет из строя.

Поэтому я добавил свойство:

@property(nonatomic, strong) LocationProfileView *locationProfile; 

и изменил вторую строку кода в:

locationProfile = [[LocationProfileView alloc] initWithLocation:l]; 

, но теперь мой класс не будет освобождаться, пока я не начать его снова (потому что это теряет ссылку на первый экземпляр LocationProfileView?). Что делать, чтобы мой класс был освобожден каждый раз, когда я нажимаю кнопку «Закрыть»? Я думаю, что установка locationProfile на nil будет работать, но это означает, что мне придется вызвать метод в основном классе (тот, который содержит блок кода).

Каков правильный способ для этого? Извините, если мои вопросы слишком нообы.

Примечание: l является экземпляром пользовательского класса, который содержит некоторые Infos, которые будут отображаться в LocationProfileView «s UIVIew.

+0

Где 'UIViewController', что вы говорите? – Richard

ответ

2
- (void)closeButtonCallBack { 
    [self.locationProfile removeFromSuperview]; 
    self.locationProfile = nil; 
} 

Я предполагаю цель вашей кнопки закрытия является само

сильный указатель ViewController будет сохранить объект до тех пор, пока сам viewController не будет освобожден, если вы не назначили ему nil

локальная переменная будет освобождена при ее удалении из сферы

АЛЬТЕРНАТИВЫ

без использования сильного указателя, вы можете сделать это

LocationProfileView *locationProfile = [[LocationProfileView alloc] initWithLocation:l]; 

UIButton *close = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
close.frame = CGRectMake(0, 100, 100, 30); 
[close addTarget:locationProfile action:@selector(removeFromSuperview) forControlEvents:UIControlEventTouchUpInside]; 
[self.view addSubview:close]; 
1

В оригинальном примере

LocationProfile *locationProfile=... 

является локальной переменной. Поэтому он выдается, как только вы возвращаетесь от конструктора. Это то, что вы наблюдали.

Когда вы сделаете это сильное свойство, контроллер вид сохраняет locationProfile:

@property(nonatomic, strong) LocationProfileView *locationProfile; 
+0

Это не обязательно будет выпущено после конструктора, но определенно, когда фрейм фрейма функции будет раздавлен. – CodaFi

+0

Извините, но это просто неправильно. Вам не нужно явно выделять сохраненное свойство в ARC, и установка локального ivar на nil не освобождает его в любом случае. – ChrisH

+0

@ChrisH «местный ивар» не имеет смысла; что вы пытались сказать? – Richard