![](/img/trans.png)
[英]Objective-c program crashes when trying to remove objects from superview
[英]Objective-C remove UIButton from Superview
我在.h文件中定义了以下UIButton:
@property (nonatomic,strong) UIButton *loginButton;
- (void)LoginButtonPressed:(UIButton *)sender;
并在我的.m文件中创建它:
@synthesize loginButton;
loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
[loginButton setFrame:CGRectMake(150.0f, 131.0f, 105.0f, 35.0f)];
[loginButton setBackgroundImage:[UIImage imageNamed:@"black_button.png"] forState:UIControlStateNormal];
[loginButton setTitle:@"Login" forState:UIControlStateNormal];
[loginButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[loginButton addTarget:self action:@selector(LoginButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
- (void)LoginButtonPressed:(UIButton *)sender
{
[self CreateActivityIndicator];
[self performSelector:@selector(Login) withObject:nil afterDelay:0.5];
}
并且我有一个名为login的方法,并且在登录时我想从超级视图中删除登录按钮。
[self.loginButton removeFromSuperview];
但是突然之间(截至昨天),我的应用开始崩溃,并在此行上引发了错误:
@property (nonatomic,strong) UIButton *loginButton;
Thread 1: EXC_BAD_ACCESS(code=1, address0x10000010)
为什么会这样呢? 以及如何解决? 昨天我确实更改了登录方式以使用AFNetworking,可以吗?
以防万一,这是我的完整方法:
- (void)Login
{
NSString *rawString = [self.idTextField text];
NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
[self.idTextField setText:[rawString stringByTrimmingCharactersInSet:whitespace]];
[userName UserLogin:self.idTextField.text andPassWordExists:self.passwordTextField.text completionHandler:^(id responseObject, NSError *error) {
if (responseObject) {
[self.idTextField removeFromSuperview];
[self.passwordTextField removeFromSuperview];
[self.loginButton removeFromSuperview];
self.idTextField = nil;
self.passwordTextField = nil;
self.loginButton = nil;
[self CreateMenu];
}else{
[self CustomAlert:@"Sorry Login Failed, User and/or Passsword Incorrect"];
}
}];
[indicatorView stopAnimating];
[indicatorView removeFromSuperview];
indicatorView = nil;
[loadingView removeFromSuperview];
loadingView = nil;
}
这是触发它的原因:
-(void)UserLogin:(NSString *)user andPassWordExists:(NSString *)password completionHandler:(void (^)(NSArray *resultsObject, NSError *error))completionHandler
{
NSURL *url = [NSURL URLWithString:kIP];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
NSURLCredential *credential = [NSURLCredential
credentialWithUser:user
password:password
persistence:NSURLCredentialPersistenceForSession];
[operation setCredential:credential];
[[NSOperationQueue mainQueue] addOperation:operation];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (completionHandler) {
completionHandler(responseObject, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (completionHandler) {
completionHandler(nil, error);
}
}];
[operation start];
}
这是我的按钮以及2个文本项被添加到视图的方式:
//add all controls to the loginView
[loginMenuView addSubview:self.idTextField];
[loginMenuView addSubview:self.passwordTextField];
[loginMenuView addSubview:self.loginButton];
更新
通过执行以下操作,我能够解决此问题:
取出self.loginButton = nil;
从我的登录方法,所以它看起来像这样:
- (void)Login
{
NSString *rawString = [self.idTextField text];
NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
[self.idTextField setText:[rawString stringByTrimmingCharactersInSet:whitespace]];
[userName UserLogin:self.idTextField.text andPassWordExists:self.passwordTextField.text completionHandler:^(id responseObject, NSError *error) {
if (responseObject) {
[self.idTextField removeFromSuperview];
[self.passwordTextField removeFromSuperview];
[self.loginButton removeFromSuperview];
self.idTextField = nil;
self.passwordTextField = nil;
//self.loginButton = nil;
[self CreateMenu];
[indicatorView stopAnimating];
[indicatorView removeFromSuperview];
indicatorView = nil;
[loadingView removeFromSuperview];
loadingView = nil;
}else{
[self CustomAlert:@"Sorry Login Failed, User and/or Passsword Incorrect"];
[indicatorView stopAnimating];
[indicatorView removeFromSuperview];
indicatorView = nil;
[loadingView removeFromSuperview];
loadingView = nil;
}
}];
}
并取出[self.loginButton removeFromSuperview];
和self.loginButton = nil;
从我的viewWillDisappear
方法像这样:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
userName = nil;
[[NSNotificationCenter defaultCenter]removeObserver:self];
[self.idTextField removeFromSuperview];
[self.passwordTextField removeFromSuperview];
//[self.loginButton removeFromSuperview];
[self.menu removeFromSuperview];
[logoutButton removeFromSuperview];
//set every control to nil
self.idTextField = nil;
self.passwordTextField = nil;
//self.loginButton = nil;
self.menu = nil;
menuItems = nil;
textfieldNavigatorView = nil;
}
这解决了我的问题,我只想知道这是否是最佳解决方案。
我认为正在发生的事情是您的loginButton与您的indicatorView或loadingView绑定在一起。
由于您使用的是完成处理程序,因此其中的代码将异步运行。 那意味着你
indicatorView = nil
或你的
loadingView = nil
在删除loginButton之前被触发。 如果loginButton是这些视图之一的子视图,则不再有对其的引用,因此您将获得BAD_ACCESS。 确保将最后五行代码(处理loadingView和indicatorView的代码)放在完成处理程序中,如下所示:
- (void)Login
{
NSString *rawString = [self.idTextField text];
NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
[self.idTextField setText:[rawString stringByTrimmingCharactersInSet:whitespace]];
[userName UserLogin:self.idTextField.text andPassWordExists:self.passwordTextField.text completionHandler:^(id responseObject, NSError *error) {
if (responseObject) {
[self.idTextField removeFromSuperview];
[self.passwordTextField removeFromSuperview];
//access the loginButton while it still has reference
[self.loginButton removeFromSuperview];
self.idTextField = nil;
self.passwordTextField = nil;
//access the loginButton while it still has reference
self.loginButton = nil;
//Then remove these views
[indicatorView stopAnimating];
[indicatorView removeFromSuperview];
indicatorView = nil;
[loadingView removeFromSuperview];
loadingView = nil;
[self CreateMenu];
}else{
[self CustomAlert:@"Sorry Login Failed, User and/or Passsword Incorrect"];
}
}];
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.