1. ホーム
  2. ios

[解決済み] iOSアプリのエラー - 自己をサブビューとして追加できない

2022-04-25 09:10:24

質問内容

このクラッシュレポートを受け取りましたが、デバッグの方法がわかりません。

Fatal Exception NSInvalidArgumentException
Can't add self as subview
0 ...    CoreFoundation  __exceptionPreprocess + 130
1    libobjc.A.dylib     objc_exception_throw + 38
2    CoreFoundation  -[NSException initWithCoder:]
3    UIKit   -[UIView(Internal) _addSubview:positioned:relativeTo:] + 110
4    UIKit   -[UIView(Hierarchy) addSubview:] + 30
5    UIKit   __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke + 1196
6    UIKit   +[UIView(Animation) performWithoutAnimation:] + 72
7    UIKit   -[_UINavigationParallaxTransition animateTransition:] + 732
8    UIKit   -[UINavigationController _startCustomTransition:] + 2616
9    UIKit   -[UINavigationController _startDeferredTransitionIfNeeded:] + 418
10   UIKit   -[UINavigationController __viewWillLayoutSubviews] + 44
11   UIKit   -[UILayoutContainerView layoutSubviews] + 184
12   UIKit   -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 346
13   QuartzCore  -[CALayer layoutSublayers] + 142
14   QuartzCore  CA::Layer::layout_if_needed(CA::Transaction*) + 350
15   QuartzCore  CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 16
16   QuartzCore  CA::Context::commit_transaction(CA::Transaction*) + 228
17   QuartzCore  CA::Transaction::commit() + 314
18   QuartzCore  CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 56

iOSのバージョンは7.0.3です。 どなたかこの奇妙なクラッシュを経験された方はいらっしゃいますか?

UPDATEしています。

私のコードのどこが原因でクラッシュしたのか分からないので、ここにコードを掲載できません。

2回目のUPDATE

以下の回答をご覧ください。

解決方法は?

私のアプリでこのクラッシュに関する詳細を説明し、これを回答としてマークします。

私のアプリにはUINavigationControllerがあり、ルートコントローラはノートオブジェクトのリストを含むUITableViewControllerです。ノートオブジェクトは、htmlのcontentプロパティを持っています。ノートを選択すると、詳細コントローラに移動します。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //get note object
    DetailViewController *controller = [[DetailViewController alloc] initWithNote:note];
    [self.navigationController pushViewController:controller animated:YES];
}

詳細コントローラ

このコントローラは、UIWebViewを持ち、ルートコントローラから渡されたノートの内容を表示します。

- (void)viewDidLoad
{
    ...
    [_webView loadHTMLString:note.content baseURL:nil];
    ...
}

このコントローラは、webview コントロールのデリゲートです。ノートにリンクが含まれている場合、リンクをタップするとアプリ内のウェブブラウザに移動します。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    WebBrowserViewController *browserController = [[WebBrowserViewController alloc] init];
    browserController.startupURL = request.URL;
    [self.navigationController pushViewController:webViewController animated:YES];
    return NO;
}

毎日、上記のようなクラッシュレポートが届きます。私のコードのどこでこのクラッシュが発生したのかわかりません。あるユーザーの助けを借りて調査した結果、ついにこのクラッシュを修正することができました。このhtmlコンテンツはクラッシュを引き起こします。

...
<iframe src="http://google.com"></iframe>
...

詳細コントローラのviewDidLoadメソッドで、このhtmlをwebviewコントロールに読み込ませ、その直後にrequest.URLはiframeのソース(google.com)で上記のデリゲートメソッドが呼び出されました。このデリゲートメソッドは、viewDidLoad =>の状態でpushViewControllerメソッドを呼び出すので、クラッシュします。

このクラッシュは、navigationTypeをチェックすることで修正しました。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    if (navigationType != UIWebViewNavigationTypeOther)
    {
        //go to web browser controller
    }
}

これが役に立つといいのですが