はい、Appleスタッフによって保持期間のバグがconfirmedがiOS 9に存在しています。
私は、保持サイクルがiOS 8.4では存在しないが、iOS 9.0および9.1では存在することをテストしました。 漏れは、私は簡単にUISplitViewControllerは(それを実行し、チェック漏れて自分自身を起こしたか否かを確認するために一緒にsample projectを入れている(iOSの9.2シミュレータ上でのXcode 7.2のベータ2でテスト)のiOS 9.2のように固定しているようですコンソール出力)。
これは、マスタービュービューコントローラと詳細ビューコントローラの割り当てを解除する試みもテストします。ご覧のように、配列プロパティから削除された後でも、マスタービューコントローラはUISplitViewController
によって保持されているように見えます。
- (void)viewDidLoad {
[super viewDidLoad];
[self testSplitViewControllerRetainCycleWithCompletion:^{
[self testManuallyFreeingUpMasterAndDetailViewControllers];
}];
}
- (void)testSplitViewControllerRetainCycleWithCompletion:(void (^)())completion {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
UIViewController *splitViewParentVC = UIViewController.new;
UIViewController *masterVC = UIViewController.new;
UIViewController *detailVC = UIViewController.new;
UISplitViewController *splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = @[masterVC, detailVC];
splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
splitViewController.preferredPrimaryColumnWidthFraction = 0.3125; // 320/1024
splitViewController.minimumPrimaryColumnWidth = 100;
[splitViewParentVC addChildViewController:splitViewController];
[splitViewParentVC.view addSubview:splitViewController.view];
[splitViewController didMoveToParentViewController:splitViewParentVC];
splitViewController.view.frame = splitViewParentVC.view.bounds;
splitViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
__weak UISplitViewController *wSplitViewController = splitViewController;
__weak UIViewController *wMaster = masterVC;
__weak UIViewController *wDetail = detailVC;
[self presentViewController:splitViewParentVC animated:YES completion:nil];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (wSplitViewController) {
NSLog(@"the split view controller has leaked");
} else {
NSLog(@"the split view controller didn't leak");
}
if (wMaster) {
NSLog(@"the master view controller has leaked");
} else {
NSLog(@"the master view controller didn't leak");
}
if (wDetail) {
NSLog(@"the detail view controller has leaked");
} else {
NSLog(@"the detail view controller didn't leak");
}
completion();
});
}];
});
});
}
- (void)testManuallyFreeingUpMasterAndDetailViewControllers {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
UIViewController *splitViewParentVC = UIViewController.new;
UIViewController *masterVC = UIViewController.new;
UIViewController *detailVC = UIViewController.new;
UISplitViewController *splitViewController = [[UISplitViewController alloc] init];
splitViewController.viewControllers = @[masterVC, detailVC];
splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
splitViewController.preferredPrimaryColumnWidthFraction = 0.3125; // 320/1024
splitViewController.minimumPrimaryColumnWidth = 100;
[splitViewParentVC addChildViewController:splitViewController];
[splitViewParentVC.view addSubview:splitViewController.view];
[splitViewController didMoveToParentViewController:splitViewParentVC];
splitViewController.view.frame = splitViewParentVC.view.bounds;
splitViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
__weak UIViewController *wMaster = masterVC;
__weak UIViewController *wDetail = detailVC;
[self presentViewController:splitViewParentVC animated:YES completion:nil];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:nil];
splitViewController.viewControllers = @[UIViewController.new, UIViewController.new];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (wMaster) {
NSLog(@"the master view controller has STILL leaked even after an attempt to free it");
} else {
NSLog(@"the master view controller didn't leak");
}
if (wDetail) {
NSLog(@"the detail view controller has STILL leaked even after an attempt to free it");
} else {
NSLog(@"the detail view controller didn't leak");
}
});
});
});
}
をUPDATE:リークがIOSの9.2のように固定されているように見える(IOSの9.2シミュレータ上でのXcode 7.2ベータ2で試験)
splitviewcontrollerを終了する前に子供を削除すると、リークが修正されますか? – yuf