2015-04-09 2 views
0

Я это UIButton определено в моем файле .h:Objective-C удалить UIButton из SuperView

@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]; 

} 

и у меня есть метод логин и логин. Я хочу удалить кнопку входа из супервизора.

[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]; 

UPDATE

Я был в состоянии решить эту проблему, выполнив следующие действия:

вынимая 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; 
} 

это решило мою проблему, я просто хочу знать, если это лучшее решение.

+0

Хотели бы вы просто спрятать свою кнопку? Если нет, я объясню проблему. –

+0

Я бы подумал о том, чтобы скрыть кнопку, но я также хотел бы знать, в чем проблема – user979331

+0

Кажется, вы остановите индикатор и удалите его вместе с загрузочным представлением до завершения обработчика завершения. Если это не код не в обработчике завершения. –

ответ

0

Что я думаю, так это то, что ваш loginButton привязан к вашему индикатору или загрузке.

Поскольку вы используете обработчик завершения, код внутри него будет запускаться асинхронно. Это означает, что ваш

indicatorView = nil 

или ваш

loadingView = nil 

в настоящее время запускается до вашего loginButton удаляется. Если loginButton является подпунктом одного из этих представлений, больше ничего не ссылается на него, поэтому вы получаете BAD_ACCESS. Удостоверьтесь, что вы поместили последние 5 строк кода (те, которые имеют дело с загрузкой и индикатором) внутри вашего обработчика завершения следующим образом:

- (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"]; 
    } 
}]; 

} 
+0

Я попробовал решение, я все равно получаю ту же ошибку – user979331

Смежные вопросы