iOS-删除所有子视图后重新添加子视图

iOS-删除所有子视图后重新添加子视图,ios,objective-c,iphone,uiview,uigesturerecognizer,Ios,Objective C,Iphone,Uiview,Uigesturerecognizer,我正在制作一个ball程序,您可以通过长按手势将ball UIView子视图添加到superview。点击视图将其从superview中删除 添加所有视图效果很好,重新添加视图效果很好,因为superview中至少还有一个视图。但是,一旦删除所有子视图,长按应该会再次重新添加第一个子视图,但程序会关闭 我在其中一个线程中只收到一条发布消息,这让我相信这是一个alloc/Dealoc问题,但ARC禁止我明确发布视图,我相信[removeFromSuperview]无论如何都会这样做 我不确定我错过

我正在制作一个ball程序,您可以通过长按手势将ball UIView子视图添加到superview。点击视图将其从superview中删除

添加所有视图效果很好,重新添加视图效果很好,因为superview中至少还有一个视图。但是,一旦删除所有子视图,长按应该会再次重新添加第一个子视图,但程序会关闭

我在其中一个线程中只收到一条发布消息,这让我相信这是一个alloc/Dealoc问题,但ARC禁止我明确发布视图,我相信[removeFromSuperview]无论如何都会这样做

我不确定我错过了什么。感兴趣的特定方法是tapped:,并且在所有子视图上都使用了createBall after tapped:

ViewController.m

以下是我能从线程错误中真正找到的所有内容:

UIKit`UIApplicationMain:
    0x10acd4bc9 <+0>:   pushq  %rbp
    0x10acd4bca <+1>:   movq   %rsp, %rbp
    0x10acd4bcd <+4>:   pushq  %r15
    0x10acd4bcf <+6>:   pushq  %r14
    0x10acd4bd1 <+8>:   pushq  %r13
    0x10acd4bd3 <+10>:  pushq  %r12
    0x10acd4bd5 <+12>:  pushq  %rbx
    0x10acd4bd6 <+13>:  pushq  %rax
    0x10acd4bd7 <+14>:  movq   %rcx, %rbx
    0x10acd4bda <+17>:  movq   %rsi, -0x30(%rbp)
    0x10acd4bde <+21>:  movl   %edi, %r12d
    0x10acd4be1 <+24>:  movq   0xe7f7b8(%rip), %r13      ; (void *)0x0000000109c12cb0: objc_retain
    0x10acd4be8 <+31>:  movq   %rdx, %rdi
    0x10acd4beb <+34>:  callq  *%r13
    0x10acd4bee <+37>:  movq   %rax, %r14
    0x10acd4bf1 <+40>:  movq   %rbx, %rdi
    0x10acd4bf4 <+43>:  callq  *%r13
    0x10acd4bf7 <+46>:  movq   %rax, %r15
    0x10acd4bfa <+49>:  leaq   0x11dab6b(%rip), %r13     ; _UIApplicationLinkedOnVersion
    0x10acd4c01 <+56>:  movl   (%r13), %eax
    0x10acd4c05 <+60>:  testl  %eax, %eax
    0x10acd4c07 <+62>:  jne    0x10acd4c17               ; <+78>
    0x10acd4c09 <+64>:  cmpq   $-0x1, 0x11d4ab7(%rip)    ; WebKitSetIsClassic + 7
    0x10acd4c11 <+72>:  jne    0x10acd4c8a               ; <+193>
    0x10acd4c13 <+74>:  movl   (%r13), %eax
    0x10acd4c17 <+78>:  cmpl   $0x20100, %eax            ; imm = 0x20100 
    0x10acd4c1c <+83>:  jb     0x10acd4c42               ; <+121>
    0x10acd4c1e <+85>:  callq  0x10b8f8a8a               ; symbol stub for: objc_autoreleasePoolPush
    0x10acd4c23 <+90>:  movq   %rax, %r13
    0x10acd4c26 <+93>:  movl   %r12d, %edi
    0x10acd4c29 <+96>:  movq   -0x30(%rbp), %rsi
    0x10acd4c2d <+100>: movq   %r14, %rdx
    0x10acd4c30 <+103>: movq   %r15, %rcx
    0x10acd4c33 <+106>: callq  0x10acd4ca2               ; _UIApplicationMainPreparations
    0x10acd4c38 <+111>: movq   %r13, %rdi
    0x10acd4c3b <+114>: callq  0x10b8f8a84               ; symbol stub for: objc_autoreleasePoolPop
    0x10acd4c40 <+119>: jmp    0x10acd4c54               ; <+139>
    0x10acd4c42 <+121>: movl   %r12d, %edi
    0x10acd4c45 <+124>: movq   -0x30(%rbp), %rsi
    0x10acd4c49 <+128>: movq   %r14, %rdx
    0x10acd4c4c <+131>: movq   %r15, %rcx
    0x10acd4c4f <+134>: callq  0x10acd4ca2               ; _UIApplicationMainPreparations
    0x10acd4c54 <+139>: movq   0x11daa55(%rip), %rdi     ; UIApp
    0x10acd4c5b <+146>: movq   0x11489d6(%rip), %rsi     ; "_run"
    0x10acd4c62 <+153>: callq  *0xe7f728(%rip)           ; (void *)0x0000000109c15ac0: objc_msgSend
    0x10acd4c68 <+159>: movq   0xe7f729(%rip), %rbx      ; (void *)0x0000000109c12d20: objc_release
    0x10acd4c6f <+166>: movq   %r15, %rdi
    0x10acd4c72 <+169>: callq  *%rbx
    0x10acd4c74 <+171>: movq   %r14, %rdi
    0x10acd4c77 <+174>: callq  *%rbx
    0x10acd4c79 <+176>: xorl   %eax, %eax
    0x10acd4c7b <+178>: addq   $0x8, %rsp
    0x10acd4c7f <+182>: popq   %rbx
    0x10acd4c80 <+183>: popq   %r12
    0x10acd4c82 <+185>: popq   %r13
    0x10acd4c84 <+187>: popq   %r14
    0x10acd4c86 <+189>: popq   %r15
    0x10acd4c88 <+191>: popq   %rbp
    0x10acd4c89 <+192>: retq   
    0x10acd4c8a <+193>: leaq   0x11d4a37(%rip), %rdi     ; _UIApplicationLinkedOnVersionOnce
    0x10acd4c91 <+200>: leaq   0xe82d08(%rip), %rsi      ; __block_literal_global.1554
    0x10acd4c98 <+207>: callq  0x10b8f92d6               ; symbol stub for: dispatch_once
    0x10acd4c9d <+212>: jmp    0x10acd4c13               ; <+74>

双击球时,将从其superview中删除该视图:

- (void)tapped:(UITapGestureRecognizer *)recognizer {
    //Delete tapped ball
    [recognizer.view willRemoveSubview:recognizer.view];
    [recognizer.view removeFromSuperview];
}
然而,这个球仍然存在。在下一次长按时,您的代码跳过创建球,因为它们都存在,但在ball create方法中,您可以将它们添加到主视图中。当您的代码进入physics方法时,您将尝试向不在层次结构中的视图添加冲突行为

从球的超级视图中删除球时,应将球设置为零,或者下次将球作为子视图重新添加

这是一种方法,虽然不是最好的

- (void)tapped:(UITapGestureRecognizer *)recognizer {
    //Delete tapped ball
    [recognizer.view willRemoveSubview:recognizer.view];
    [recognizer.view removeFromSuperview];

    if (recognizer.view == _blueBall) {
        _blueBall = nil;
    } else if (recognizer.view == _orangeBall) {
        _orangeBall = nil;
    }
}

如果你想让人们阅读你的问题,请不要发布不相关的代码,例如updateView、didReceiveMemoryWarning。找出出现问题的代码的最小数量也有助于找出根本原因。如果你移除了物理方法,或者BallDraged方法或者其中的一部分,这个问题还会发生吗?如果没有,则不包括它们。改进,但设置球的颜色等是否会影响行为?如果没有,请删除这些方法。删除与当前问题无关的任何属性。继续,直到你有最少的代码显示问题。您可能会发现创建一个自己的新临时项目来调查此问题非常有用。谢谢。我实际上尝试过使用_orangeBall=nil,但没有if条件,也没有帮助,但效果很好。我的代码需要很多重构,但我现在的主要目标是功能性。对Objective-C来说还是新手。谢谢你的帮助!
- (void)tapped:(UITapGestureRecognizer *)recognizer {
    //Delete tapped ball
    [recognizer.view willRemoveSubview:recognizer.view];
    [recognizer.view removeFromSuperview];

    if (recognizer.view == _blueBall) {
        _blueBall = nil;
    } else if (recognizer.view == _orangeBall) {
        _orangeBall = nil;
    }
}