App*_*eyA 1 cocoa-touch memory-management objective-c ios ios7
我已经开发了一个应用程序大约一个星期左右,我认为这是一个好时机来分析它以确保我正在做的一切正确,我发现即使我的所有对象都得到了dealloc'd分配金额正在上升.当我释放一个对象时,我会执行以下操作:
[object release];
object = nil;
Run Code Online (Sandbox Code Playgroud)
在我的应用程序我有确定任一示出了初始视图控制器我的LoginViewController或TimeLineViewController,取决于我是否有访问令牌.(这部分并不重要,因为我遇到的问题是LoginViewController/ SignupViewController.).登录控制器有两个文本字段和两个按钮,这些按钮将sVC推送到导航视图控制器或尝试登录.
奇怪的是,dealloc在我的视图和视图控制器上调用这些方法,但是在调用它们之后内存会上升.
SDK版本7.0 Xcode版本5.0
编辑:
在我的LoginViewController中,当我从LoginView获取单击SignupButton的事件时,将调用此方法:
- (void)signupButtonPressed
{
SignupViewController *signupVC = [[SignupViewController alloc] init];
[self.navigationController pushViewController:signupVC animated:true];
destroy(signupVC);
}
Run Code Online (Sandbox Code Playgroud)
***注意,销毁宏如下:
#define destroy($x) \
if($x) \
{ \
[$x release]; \
$x = nil; \
}
Run Code Online (Sandbox Code Playgroud)
创建SignupViewController时,ViewDidLoad方法如下:
self.view = [[SignupView alloc] initWithFrame:self.view.frame];
[[(SignupView *)self.view evtSignupButtonPressed] addHandler:AFFHandler(@selector(signupPressed))];
[((SignupView *)self.view).profileImage addTarget:self action:@selector(profileImagePressed) forControlEvents:UIControlEventTouchUpInside];
[self.navigationController setNavigationBarHidden:false animated:true];
Run Code Online (Sandbox Code Playgroud)
然后它为SignupView中的视图创建UI,如下所示:
- (void)setupUI
{
self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:IS_IPHONE5 ? @"genericBackground-568h.jpg" : @"genericBackground.jpg"]];
_overlayView = [[UIView alloc] initWithFrame:self.frame];
_scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
_profileImage = [[UIButton alloc] init];
profileImageContainer = [[UIView alloc] initWithFrame:CGRectMake(18.5, 0, _profileImage.imageView.image.size.width + 10, _profileImage.imageView.image.size.height + 10)];
selectProfilePictureText = [[UILabel alloc] initWithFrame:CGRectMake(profileImageContainer.affX, 0, 229, 17)];
UIView *padding = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 17, 40)];
_usernameField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)];
_usernameField.delegate = self;
_passwordField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)];
_passwordField.delegate = self;
_repeatPasswordField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)];
_repeatPasswordField.delegate = self;
_emailField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 284, 40)];
_emailField.delegate = self;
destroy(padding);
buttonImage = [[UIImage imageNamed:@"largeButton.png"] copy];
_submitButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, buttonImage.size.width, buttonImage.size.height)];
[_submitButton addTarget:self action:@selector(signupButtonPressed) forControlEvents:UIControlEventTouchUpInside];
destroy(buttonImage);
[self addSubview:_scrollView];
[self addSubview:_overlayView];
[_scrollView addSubview:profileImageContainer];
[profileImageContainer addSubview:_profileImage];
[_scrollView addSubview:selectProfilePictureText];
[_scrollView addSubview:_usernameField];
[_scrollView addSubview:_passwordField];
[_scrollView addSubview:_repeatPasswordField];
[_scrollView addSubview:_emailField];
[_scrollView addSubview:_submitButton];
destroy(profileImageContainer);
destroy(selectProfilePictureText);
}
Run Code Online (Sandbox Code Playgroud)
**注意,我已经省略了所有改变了这些对象属性的代码,例如更改backgroundColour等.
SignupVC和SignupView的dealloc方法如下:
SignupView:
- (void)dealloc
{
self.usernameField.delegate = nil;
self.passwordField.delegate = nil;
self.repeatPasswordField.delegate = nil;
self.emailField.delegate = nil;
AFFRemoveAllEvents();
destroyAndRemove(_usernameField);
destroyAndRemove(_passwordField);
destroyAndRemove(_repeatPasswordField);
destroyAndRemove(_emailField);
destroyAndRemove(_profileImage);
destroyAndRemove(_submitButton);
destroyAndRemove(_scrollView);
destroyAndRemove(_overlayView);
if(buttonImage)
destroy(buttonImage);
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
SignupVC(在按下NavigationBar的后退按钮后调用它)
- (void)dealloc
{
[[(SignupView *)self.view evtSignupButtonPressed] removeHandlersForObserver:self];
[((SignupView *)self.view).profileImage removeTarget:self action:@selector(profileImagePressed) forControlEvents:UIControlEventTouchUpInside];
destroy(profileImage);
destroyAndRemove(self.view);
[super dealloc];
}
Run Code Online (Sandbox Code Playgroud)
DestroyAndRemove这样做:
#define destroyAndRemove($x) \
if($x) \
{ \
[$x removeFromSuperview]; \
[$x release]; \
$x = nil; \
}
Run Code Online (Sandbox Code Playgroud)
切换到ARC.说真的,没有充分的理由不使用它,甚至可能修复你的记忆问题:
1)Apple强烈鼓励并表示他们ARC在更新和新应用中使用它们.
2)绝大多数新的应用程序提交和更新都使用ARC,并且在绝大多数情况下它已被证明与手动引用计数一样有效(您的应用程序可能不是例外).
3)ARC简化您作为Objective-C开发人员的生活.你不必用垃圾代码release,retain等随处可见了.
4)有一个易于使用的转换工具:
转到Edit> Refactor>Convert to Objective C ARC
5)即使您使用的是尚未切换到ARC的第三方库(最常用的已经拥有),您也可以选择不使用ARC单个文件.看到这篇关于如何做的SO帖子.
如果您在切换到后仍然遇到问题ARC- 如上所述,切换到ARC可能会修复您的内存问题 - 请回来,我们将再次提出.
| 归档时间: |
|
| 查看次数: |
306 次 |
| 最近记录: |