简体   繁体   中英

UIView is slow to be removed from superview

I'm adding a UIView to the window while some threaded background updates are happening, then use a delegate method to remove the view. Everything is happening as intended, but the view remains for several seconds after hideActivityViewer is called. Not sure if it matters, but the app uses a UITabBarController.

The updating methods were in a separate class but are currently in AppDelegate.m for debugging purposes. As I said, everything works. When the updates are complete, it writes "Foo" to the log, but the view persists for several seconds. Any help would be appreciated. Superfluous code has been omitted:

AppDelegate.h

@interface AppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
  UIWindow *window;
  UITabBarController *tabBarController;
  UIView *activityView;
  id _delegate;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) UITabBarController *tabBarController;
- (void)showActivityViewer;
- (void)updateComplete;
- (void)updateRemoteDataThreadedWithDelegate:(id)aDelegate;
- (id)delegate;
- (void)setDelegate:(id)new_delegate;
@end

AppDelegate.m

- (void)updateRemoteDataThreadedWithDelegate:(id)aDelegate {
  [self setDelegate:aDelegate];
  NSOperationQueue *queue = [NSOperationQueue new];
  NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(updateRemoteDataWithDelegate:) object:aDelegate];
  [queue addOperation:operation];
  [operation release];
}

- (void)updateRemoteDataWithDelegate:(id)aDelegate {
  [self setDelegate:aDelegate];
  ...do stuff...
  if ([_delegate respondsToSelector:@selector(updateComplete)]) {
    [_delegate updateComplete];
  } else { 
    [NSException raise:NSInternalInconsistencyException format:@"Delegate doesn't respond to updateComplete"];
  }
}

-(void)showActivityViewer {
  [activityView release];
  activityView = [[UIView alloc] initWithFrame: CGRectMake(window.bounds.size.width-50, 60, 50, 50)];
  ...formatting...
  [window addSubview: activityView];
  [activityView release];
}
-(void)hideActivityViewer {
  [activityView removeFromSuperview];
  activityView = nil;
  NSLog(@"Foo");
}

- (id)delegate {
  return _delegate;
}

- (void)setDelegate:(id)new_delegate {
  _delegate = new_delegate;
}

It looks to me like you are causing a thread to call a delegate method which does stuff in UIView - you can't do that since UIView is not thread-safe.

Use performSelectorOnMainThread to do this safely - your delegate method could call another method on the main thread this way.

UI operations should be done on the main thread; your example pushes UIView onto a separate thread, which is not recommended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM