Как обращаться с управлением памятью для настройки / демонтажа пользовательских модальных диалогов - PullRequest
0 голосов
/ 24 января 2011

В настоящее время мое приложение использует пользовательский модальный диалоговый объект, когда я жду веб-службы

@implementation AddModalDialog

- (void)buildModalDialogWithTextForView:(NSString *)text:(UIViewController *)controller
{
  UIView* _hudView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 400, 450)];
  _hudView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
  _hudView.clipsToBounds = YES;

  UIActivityIndicatorView* _activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
  _activityIndicatorView.frame = CGRectMake(140, 135, _activityIndicatorView.bounds.size.width, _activityIndicatorView.bounds.size.height);
  [_hudView addSubview:_activityIndicatorView];
  [_activityIndicatorView startAnimating];

  UILabel* _captionLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 190, 250, 22)];
  _captionLabel.backgroundColor = [UIColor clearColor];
  _captionLabel.textColor = [UIColor whiteColor];
  _captionLabel.font = [UIFont systemFontOfSize:13.0];
  _captionLabel.adjustsFontSizeToFitWidth = NO;
  _captionLabel.textAlignment = UITextAlignmentCenter;
  _captionLabel.text = text;
  [_hudView addSubview:_captionLabel];

  [controller.view addSubview:_hudView];
}

- (void)removeModalDialogForView:(UIViewController *)controller
{
  NSUInteger i, count = [controller.view.subviews count];
  [[controller.view.subviews objectAtIndex:(count - 1)] removeFromSuperview];
}

@end

Мой вопрос связан с управлением памятью при использовании этого объекта. И все, что вы можете заметить в пользовательском UIView выше, приветствуется, поскольку в нем есть возможности для улучшения, я уверен.

Вот как я сейчас работаю с другими объектами, когда хочу открыть модальное

- (void)viewDidLoad
{
  AddModalDialog* modal = [[AddModalDialog alloc] init];
  [modal buildModalDialogWithTextForView:@"Loading some details ..." :self];
  [modal release];
}

Затем, после завершения веб-службы, я обычно называю демонтаж

- (void)returnWebServiceDetails:(MyClass *)obj
{ 
  AddModalDialog* modal = [[AddModalDialog alloc] init];
  [modal removeModalDialogForView:self];
  [modal release];
}

Разве я не должен инициировать этот объект дважды и вместо этого иметь свойство? Новый разработчик obj-c ищет лучшую практику в этом направлении.

Заранее спасибо

Ответы [ 2 ]

2 голосов
/ 24 января 2011

Во-первых, вы фактически переносите владение этими элементами в представление контроллера (поскольку у вас нет ссылок на них), поэтому вы должны освободить их все после добавления их в подпредставление контроллера.предполагая, что вы знаете структуру иерархии представлений контроллера, вы должны вместо этого пометить свой _hudView чем-то, что, как мы надеемся, не конфликтует с чем-либо еще в вашем приложении, и использовать это для получения своего представления.вы вообще не держите никаких ссылок, лучше использовать их как методы класса, а не как экземпляры.Нет необходимости создавать экземпляр этого объекта, просто чтобы он добавил несколько представлений и удалился.

Таким образом, ваш тот же код, следуя этим трем рекомендациям, может выглядеть так:

@interface AddModalDialog {
}

+ (void)buildModalDialogWithText:(NSString *)text forController:(UIViewController *)controller;
+ (void)removeModalDialogForController:(UIViewController *)controller;

@end

@implementation AddModalDialog

// Class methods: use '+' instead of '-'
+ (void)buildModalDialogWithText:(NSString *)text forController:(UIViewController *)controller
{
  UIView* _hudView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 400, 450)];
  _hudView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
  _hudView.clipsToBounds = YES;
  _hudView.tag = 2000; // use something that won't clash with tags you may already use

  UIActivityIndicatorView* _activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
  _activityIndicatorView.frame = CGRectMake(140, 135, _activityIndicatorView.bounds.size.width, _activityIndicatorView.bounds.size.height);
  [_hudView addSubview:_activityIndicatorView];
  [_activityIndicatorView startAnimating];
  [_activityIndicatorView release]; // _hudView owns this now

  UILabel* _captionLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, 190, 250, 22)];
  _captionLabel.backgroundColor = [UIColor clearColor];
  _captionLabel.textColor = [UIColor whiteColor];
  _captionLabel.font = [UIFont systemFontOfSize:13.0];
  _captionLabel.adjustsFontSizeToFitWidth = NO;
  _captionLabel.textAlignment = UITextAlignmentCenter;
  _captionLabel.text = text;
  [_hudView addSubview:_captionLabel];
  [_captionLabel release]; // _hudView owns this now

  [controller.view addSubview:_hudView];
  [_hudView release]; // the controller's view owns this now
}

// Class methods: use '+' instead of '-'
+ (void)removeModalDialogForController:(UIViewController *)controller
{
  UIView* _hudView = [controller.view viewWithTag:2000];
  [_hudView removeFromSuperView]; // owned by the view, so we don't need to do anything more
}

@end

И вы бы это использовали:

- (void)viewDidLoad
{
  // Class methods, so we don't need to create an instance to use
  [AddModalDialog buildModalDialogWithText:@"Loading some details..." forController:self];
}

- (void)returnWebServiceDetails:(id)obj
{
  // Class methods, so we don't need to create an instance to use
  [AddModalDialog removeModalDialogForController:self];
}
2 голосов
/ 24 января 2011

В buildModalDialogWithTextForView внизу сделайте релиз на _activityIndicatorView, _captionLabel и _hudView - вы являетесь их владельцем (создавая их). В противном случае они просто протекут.

Подробнее о Владение и распоряжение объектами и CoreFoundation Политика владения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...