2013-02-11 4 views
0

문제를 설명해 드리겠습니다. 3 UIView : LoginView, LibraryViewStoreView입니다. 나는 하나의 UIView에서 다른 전환이 코드를 가지고 :UIView removeFromSuperview로 인해 앱이 손상됩니다.

- (void)showView:(NSInteger)viewTag 
{ 
    if (viewTag == 1) 
    { 
     if (self.loginView) 
     { 
     self.loginView = nil; 
     self.loginView.delegate = nil; 
     } 

     LoginView *loginPage = [[LoginView alloc]initWithFrame:self.view.bounds]; 
     [loginPage setDelegate:self]; 

     self.loginView = loginPage; 

     [loginPage release]; 

     [self.view addSubview:self.loginView]; 
} 
else if(viewTag == 2) 
{ 
    if (self.libraryView) 
    { 
     self.libraryView = nil; 
     self.libraryView.delegate = nil; 
    } 

    LibraryView *libraryPage = [[LibraryView alloc]initWithFrame:self.view.bounds]; 
    [libraryPage setDelegate:self]; 

    self.libraryView = libraryPage; 

    [libraryPage release]; 

    [self.view addSubview:self.libraryView]; 
} 
else 
{ 
    if (self.bookStoreView) 
    { 
     self.bookStoreView = nil; 
     self.bookStoreView.delegate = nil; 
    } 

    BookStoreView *bookStore = [[BookStoreView alloc]initWithFrame:self.view.bounds]; 
    [bookStore setDelegate:self]; 

    self.bookStoreView = bookStore; 

    [bookStore release]; 

    [self.view addSubview:self.bookStoreView]; 
} 

}

는 기본적으로, 그 내가 UIViews를 초기화하는 방법입니다. 그리고 여기 사이를 전환하는 데 사용되는 버튼과 같다 : 내가 기능을 libraryViewToLoginViewstoreViewToLoginView를 호출 할 때

- (void)loginViewToLibraryView 
    { 
    [self.loginView removeFromSuperview]; 
    [self showView:2]; 
    } 

- (void)libraryViewToStoreView 
    { 
    [self.libraryView removeFromSuperview]; 
    [self showView:3]; 
    } 

    //so on... 

문제가 발생한다. 두 함수가 이전에 제대로 작동했기 때문에 이상한 함수를 호출 할 때마다 응용 프로그램이 충돌합니다. 나는 프로필 확인하고 그것은 나에게이 스택 트레이스 주었다

당신이 볼 수 있듯이
# Address  Category Event RefCt Timestamp Size Responsible Library Responsible Caller 
0 0xc4dcac0 CALayer Malloc 1 00:02.233.004 48 UIKit     -[UIView _createLayerWithFrame:] 
1 0xc4dcac0 CALayer Retain 3 00:02.238.317 0 QuartzCore    CA::Layer::insert_sublayer(CA::Transaction*, CALayer*, unsigned long) 
2 0xc4dcac0 CALayer Release 2 00:02.238.324 0 UIKit     -[UIView(Internal) _addSubview:positioned:relativeTo:] 
3 0xc4dcac0 CALayer Retain 3 00:02.238.518 0 QuartzCore   -[CALayerArray copyWithZone:] 
4 0xc4dcac0 CALayer Release 2 00:02.238.602 0 UIKit     -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] 
5 0xc4dcac0 CALayer Retain 3 00:02.238.665 0 QuartzCore   -[CALayerArray copyWithZone:] 
6 0xc4dcac0 CALayer Release 2 00:02.238.796 0 UIKit     -[UIView(Internal) _didMoveFromWindow:toWindow:] 
7 0xc4dcac0 CALayer Retain 3 00:05.107.397 0 QuartzCore   -[CALayerArray copyWithZone:] 
8 0xc4dcac0 CALayer Release 2 00:05.107.539 0 UIKit     -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] 
9 0xc4dcac0 CALayer Retain 3 00:05.107.613 0 QuartzCore   -[CALayerArray copyWithZone:] 
10 0xc4dcac0 CALayer Release 2 00:05.107.700 0 UIKit     -[UIView(Internal) _didMoveFromWindow:toWindow:] 
11 0xc4dcac0 CALayer Retain 2 00:06.105.958 0 QuartzCore   -[CALayerArray copyWithZone:] 
12 0xc4dcac0 CALayer Release 2 00:06.108.134 0 UIKit     -[UIView dealloc] 
13 0xc4dcac0 CALayer Release 1 00:06.108.492 0 UIKit     -[UIView dealloc] 
14 0xc4dcac0 CALayer Zombie -1 00:06.115.332 0 QuartzCore   CA::release_objects(X::List<void const*>*) 

, 그것이 내가 정말 이해가되지 않는의 CALayer의 통화의 무리입니다. 왜 이런 일이 일어 났는지 이해하고 싶습니다. 아무도 설명 할 수 있을까요?

+0

좀비 프로세스가 있습니다. 할당 취소 된 객체를 해제하고 있습니다. Instruments를 사용하여 메모리 누수를 분석하십시오. 우리에게 loginView 및 libraryView의 @property를 보여 주며, 강건합니까/보유합니까? – mientus

+0

최근에 만든보기를 하위보기로 추가 한 후에이보기를 해제하려고 시도 했습니까? 전 ARC obj C에 익숙하지 않지만 뷰에 하위 뷰를 추가하면 새로운 강력한 참조가 만들어 지므로이 줄 (및 비슷한 줄)을 바꿀 수 있습니다. [bookStore release]; [self.view addSubview : self.bookStoreView]; – guenis

+0

'loginView','libraryView' 및'bookStoreView'가 속성을 보유하고 있는지 여부를 알고 싶습니다. – Ilanchezhian

답변

0

솔직히 여기서 원하는 모든 것을 이해하지 못했습니다. 그러나 사건의 순서를 고려해야합니다. 내 의견보기 :

if (self.loginView) 
    { 
    self.loginView = nil; 
    //self.loginView is nil now. What so you think doese happen on the next line? 
    self.loginView.delegate = nil; 
    // change the sequence of this lines and it will be ok. 
    } 

    LoginView *loginPage = [[LoginView alloc]initWithFrame:self.view.bounds]; 
    [loginPage setDelegate:self]; 

    self.loginView = loginPage; 

    [loginPage release]; //here you release the object. it is gone now. However, there are still references to it. 

    [self.view addSubview:self.loginView]; // here you add the released object. What do you expect to happen? 
    // Switch those two statmetns and you should be fine. 

글쎄, 심지어 그 statmens 서로 옆에있는 것처럼 작동 할 수 있습니다. 그리고 슈퍼 뷰에서 제거하면 다시 릴리즈됩니다. 그리고 앱이 다운 될 수도 있습니다.

동의어를 사용하지 않고는 전혀 공개하지 않아야합니다. 아니면 내가 틀린거야? 그러나 addSubview는이를 유지해야하며 removeFromSuperview가이를 해제하므로 추가 릴리스가 필요하지 않습니다. 한 번은 없어져야한다고했습니다. (다른 곳에 보관하지 않은 경우)

+0

응답 해 주셔서 감사합니다! 그러나 모든 정직함에서 나는 그것을 완전히 이해하지 못한다. 나는 다른 프로그래머로부터 그것을 물려 받았고 나는 여전히 흐름을 배우는 과정에있다. 그래서 나를 도와 줘서 고마워! 작동하는 경우 귀하의 답변을 수락합니다. –

+0

좋습니다. 다음은 오래된 코드입니까? 그렇기 때문에 Automatic Reference Counting을 사용하지 않는 이유는 무엇입니까? 새 프로젝트의 경우 사용을 고려해야합니다. 메모리 관리로 인한 많은 고통이 사라졌습니다. –

+0

예. Xcode에서 Refactor를 사용하여 ARC로 변환하려고했지만 일부에서는 변환하지 못하도록하는 것이라고 말합니다. 나는 ARC로 변환하기위한 것들을 찾을 충분한 시간이 없으므로 지금 그대로두고 떠나기로 결정했다. –

관련 문제