目前我的应用程序在等待Web服务时使用自定义模式对话框对象
@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];
}
然后,在完成Web服务之后,我通常会将其拆除
- (void)returnWebServiceDetails:(MyClass *)obj
{
AddModalDialog* modal = [[AddModalDialog alloc] init];
[modal removeModalDialogForView:self];
[modal release];
}
我不应该两次初始化此对象而是拥有属性吗?新的obj-c开发人员正在寻找围绕此行为的最佳实践。
提前谢谢
答案 0 :(得分:2)
在buildModalDialogWithTextForView
底部,在_activityIndicatorView
,_captionLabel
和_hudView
上发布 - 您是这些人的所有者(通过创建它们)。否则,它们就会泄漏。
有关Object Ownership and Disposal和CoreFoundation Ownership Policy
的更多信息答案 1 :(得分:2)
首先,您有效地将这些项目的所有权转移到控制器的视图中(因为您没有对它们进行任何引用),因此您应该在将它们添加到控制器的子视图后将它们全部释放。
其次,不应该假设您知道控制器视图层次结构的结构,而应该使用希望与应用程序中的任何其他内容不冲突的内容标记_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];
}