Я swizzling willMoveToWindow:
, и я столкнулся с проблемой, когда его дважды вызывали на представления.willMoveToWindow называется дважды
Когда новый контроллер представления выталкивается на UINavigationController
,
willMoveToWindow:
вызывается на существующем виде с nil
значения (имеет смысл, поскольку вид двигается закадровым)
По истечению этого времени метода willMoveToWindow:
вызывается снова, но теперь с оригинальным окном.
Моя первая мысль, что swizzling и вызывая window
свойство перед оригинальный метод проломил.
Чтобы быть на безопасной стороне я создал небольшой образец проекта и подтвердил то же самое поведение.
В принципе мне нужен способ, чтобы знать наверняка, что вид не на window
(Потому что я запуск логики, когда вид двигается к окну, которое в действительности не должно быть запущенно (по крайней мере, не в два раза))
Для справки проблема может быть воспроизведена с помощью следующего кода:
@implementation RandomView
-(void)willMoveToWindow:(UIWindow *)newWindow {
// when the new view controller is pushed -
//the method is called twice on the existing view (on the screen view)-
//first time will be called with nil -
//second time with the original window
NSLog(@"********%s <RandomView %p> <Window %p>",__PRETTY_FUNCTION__,self,newWindow);
}
-(void)didMoveToWindow {
NSLog(@"********%s <RandomView %p> <Window %p>",__PRETTY_FUNCTION__,self,self.window);
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
RandomView *k = [[RandomView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:k];
}
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
ViewController *vc = [[ViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
});
});
//[self becomeFirstResponder];
}
@end
EDIT консоли
[RandomView willMoveToWindow:] <RandomView 0x7f8b21e16630> <Window 0x7f8b21d220d0>
[RandomView didMoveToWindow] <RandomView 0x7f8b21e16630> <Window 0x7f8b21d220d0>
//THIS IS THE ISSUE
[RandomView willMoveToWindow:] <RandomView 0x7f8b21e16630> <Window 0x0>
[RandomView didMoveToWindow] <RandomView 0x7f8b21e16630> <Window 0x0>
[RandomView willMoveToWindow:] <RandomView 0x7f8b21e16630> <Window 0x7f8b21d220d0>
[RandomView didMoveToWindow] <RandomView 0x7f8b21e16630> <Window 0x7f8b21d220d0>
[RandomView willMoveToWindow:] <RandomView 0x7f8b21e16630> <Window 0x0>
[RandomView didMoveToWindow] <RandomView 0x7f8b21e16630> <Window 0x0>
Не можете ли вы проверить 'view.window'? Зачем вам нужно подпевать? Swizzling - это плохо. – Andy
Это не относится к делу - это было просто примечание. Проблема в том, что она называется дважды - –
Это имеет смысл для меня. 1. ViewDidLoad добавляет подвыборы 2. В окно добавляется вид. С этой цепочкой команд вы должны получить два вызова willMoveToWindow. Вы можете использовать какой-либо флаг или что-то, чтобы зарегистрировать соответствующие события. – Andy