2012-05-16 4 views
1

iOS 앱 충돌 문제를 디버깅하는 데 시간이 많이 걸리고 있습니다. 내가 UIViewloadView에 정의한 UIViewController이있다. 나는 또한 UIView 사본을 보유하여 (뷰가 회전 된 것과 같은) 메시지를 보낼 수 있습니다. 이 외에도 UIView에는 부모에 대한 연결을 포함하는 자체 대리인 구성원 (할당 사용, 부모에 대한 참조 유지 안 함)이 있습니다. (이것은 Apple 문서 중 하나에서 사용되는 패턴입니다. 두 객체간에 순환 참조가 있기 때문에 이것이 내 문제의 일부가 아닌지 궁금합니다.UIViewController 무작위 할당 취소

다음은 객체의 계층 적보기입니다.

UIViewController + UIView + NSNotificationCenter UIKeyboardDidShow

NSNotificationUIKeyboardDidShow에 대한 화재 및 부모 대리자 메서드가 호출 될 때 문제가 발생합니다. 대의원은 이고, 세트는입니다. 그러나 어쨌든, 대의원이 석방되고 있습니다. 또한 _bufferViewDelegate으로 설정되고으로 설정됩니다. 마지막으로, 이것은 매번 발생하지 않습니다. 거의 발생하지 않습니다. 이 문제를 해결

:

Exception Type: EXC_CRASH (SIGABRT) 
Exception Codes: 0x00000000, 0x00000000 
Crashed Thread: 0 

Last Exception Backtrace: 
0 CoreFoundation     0x325f288f __exceptionPreprocess + 163 
1 libobjc.A.dylib     0x34648259 objc_exception_throw + 33 
2 CoreFoundation     0x325f5a9b -[NSObject doesNotRecognizeSelector:] + 175 
3 CoreFoundation     0x325f4915 ___forwarding___ + 301 
4 CoreFoundation     0x3254f650 _CF_forwarding_prep_0 + 48 
5 Buffer       0x0008716d -[BufferView scrollToCursor] (BufferView.m:4348) 
6 Buffer       0x00080407 -[BufferView keyboardDidShow:] (BufferView.m:1379) 
7 Foundation      0x37f3d4ff __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke_0 + 19 
8 CoreFoundation     0x325be547 ___CFXNotificationPost_block_invoke_0 + 71 
9 CoreFoundation     0x3254a097 _CFXNotificationPost + 1407 
10 Foundation      0x37eb13eb -[NSNotificationCenter postNotificationName:object:userInfo:] + 67 
11 UIKit       0x3209f029 -[UIInputViewTransition postNotificationsForTransitionEnd] + 789 
12 UIKit       0x3233a51f __53-[UIPeripheralHost(UIKitInternal) executeTransition:]_block_invoke_01008 + 159 
13 UIKit       0x320344db -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 215 
14 UIKit       0x3202eaab -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 471 
15 UIKit       0x320343d5 -[UIViewAnimationState animationDidStop:finished:] + 53 
16 QuartzCore      0x342dbc2f CA::Layer::run_animation_callbacks(void*) + 203 
17 libdispatch.dylib    0x35c4ae91 _dispatch_main_queue_callback_4CF$VARIANT$up + 197 
18 CoreFoundation     0x325c52ad __CFRunLoopRun + 1269 
19 CoreFoundation     0x325484a5 CFRunLoopRunSpecific + 301 
20 CoreFoundation     0x3254836d CFRunLoopRunInMode + 105 
21 GraphicsServices    0x3169f439 GSEventRunModal + 137 
22 UIKit       0x32047cd5 UIApplicationMain + 1081 
23 Buffer       0x0005c20b main (main.m:20) 
24 Buffer       0x0005bcac start + 40 

업데이트 2 : 여기

는 스택 추적입니다. 내가 한 일은 컨트롤러와 모든 하위 뷰에 NSLog 문을 넣어서 예상대로 모든 것이 릴리스되는지 확인하는 것입니다. 그렇지 않았습니다. 내가 기대하고, 대부분의 시간을 발생 무엇이었다이 : 무슨 일이 된 것은 때로는 BufferView가의 dealloc 메서드가 호출 없었이었다

UIViewController loadView <-- Open the view, init the BufferView 
UIViewController dealloc 
BufferView dealloc 

! 의 UIViewController에서

코드는 다음과 같이보고 다음의 UIViewController의 할당 해제의 방법은 내가 bufferView을 해제 할 불렸다

- (void)loadView 
{ 
    ... 

    // bufferView is a member var of this particular UIViewController 
    bufferView = [[BufferView alloc] init]; 
    [self addSubview:view]; 

    ... 
} 

. 나는에는 loadView이에 코드를 변경

- (void)dealloc 
{ 
    ... 

    [bufferView release]; 
    bufferView = nil; 

    ... 

    [super dealloc]; 
} 

:

- (void)loadView 
{ 
    ... 

    // bufferView is a member var of this particular UIViewController 
    bufferView = [[BufferView alloc] init]; 
    [self addSubview:view]; 
    [bufferView release]; 

    ... 
} 

및 할당 해제의 모든 일에 릴리스 명령을 제거 내가 예상대로 작동하기 시작했다. 보기를 하위보기에 추가 한 후보기를 해제하는 것이 가장 좋습니다. 다른 응용 프로그램에서이 패턴을 보았지만 왜 이렇게해야하는지 이해하지 못했습니다. 희망이 다른 사람을 도와줍니다.

하루 이상에 충돌이 발생하지 않았 음을 유의하십시오. 이것은 이전보다 훨씬 좋았습니다. 이것이 잘못된 해결책으로 판명되면 티켓을 업데이트 할 것입니다.

UPDATE 3

위 작동하지 않았다. 지금은 등록/UIViewController viewWillAppear, viewDidDisappear 메서드 알림을 등록 취소. 문제 해결됨.지금까지 모든 사람들의 제안을 말할 수있는 한 [[NSNotification defaultCenter] removeObserver : self] 호출을 dealloc에 ​​넣는 것입니다. 이것은 전혀 좋은 생각이 아닙니다. 은 시스템에서 개체가 발생할 것으로 예상되는 시간 내에 개체를 할당 해제 할 수 없습니다. 어쩌면 어떤 경우에는 잘 작동하지만 전부는 아닙니다. 필요할 때만 전화를 등록/등록 취소하려고 시도하는 것이 좋습니다. 제 경우에는보기가 표시 될 때만 필요하고보기가 표시되지 않을 때 등록 해제됩니다. 하루 동안 무료로 다운로드 할 수 있습니다 (Google에서 얼마나 오래 지속되는지 알 수 있습니다). 나는 성공으로 며칠 만에 업데이트 할 것이다.

문제였다

UPDATE 4. 더 이상 충돌하지 않습니다. 따라서 절대적으로 필요로 할 때만 옵서버를 등록하고 그렇지 않은 경우 등록을 취소하십시오.

+0

충돌이 발생할 때까지는 손상이 오래되었습니다. 객체가 할당 해제되면 시한 폭탄을 맞 춥니 다. –

+0

(누가 UIViewController를 보유하고 있습니까?) –

답변

1

개체가 할당 해제 된 것을 확인하려면 NSLog를 dealloc 루틴에 넣습니다. 그리고 dealloc에 주소 스톱을 배치하면 호출 스택을 표시하고 해당 객체를 해제하는 사람이 release 인 지 확인할 수 있습니다.

당신이 생각하는 것보다 오브젝트가 실제로 더 빨리 할당 해제되는 것은 의심 스럽지만 타이머 이벤트 중에 스토리지가 재활용되고 오류가 감지됩니다.

+0

UIViewController가 탐색 스택에서 튀어 나올 때만 dealloc이 실행됩니다. 내가 지금 한 것은 NSTimer를 제거하는 것입니다. 그 이후로 나는 아직 충돌을 입지 않았다. 나는 이것이 해결책에 대한 해결책이라고 생각하고 싶다. 그러나 NSTimer를 거기에 넣는다. 그런 다음 NSTimer 논리를 거기에 넣었으므로이 클래스에 대한 몇 가지 수정 사항이 있습니다. 따라서 최신 변경 사항으로 인해 "작동"할 수 있습니다. – PeqNP

+0

@echamber - 당신은 그것이 dealloced되면, 그리고 타이머가 dealloced 후 절대로 벗어나지 않는다고 생각합니다. 분명히,이 두 가정 중 하나는 틀린 것입니다. –

+0

그것이 제가 관찰 한 것입니다. 이전보기로 이동하려면 왼쪽 화살표를 클릭하면 dealloc 호출이 생성됩니다. 나는 위에서 언급 한 수정 사항을 사용하더라도 여전히 충돌한다는 점을 지적하고자했습니다. 새로운 스택 추적으로 주 질문을 업데이트했습니다. – PeqNP

관련 문제