让我解释一下我的问题。我有3个UIView
: LoginView , LibraryView 和 StoreView 。我有这个代码从一个UIView切换到另一个:
- (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的方法。以下是用于在它们之间切换的按钮:
- (void)loginViewToLibraryView
{
[self.loginView removeFromSuperview];
[self showView:2];
}
- (void)libraryViewToStoreView
{
[self.libraryView removeFromSuperview];
[self showView:3];
}
//so on...
当我调用函数libraryViewToLoginView
和storeViewToLoginView
时出现问题。每当我调用这些函数时应用程序崩溃,这很奇怪,因为之前两个函数都正常工作。我检查了Profile,它给了我这个堆栈跟踪:
# 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 :(得分: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.
嗯,它甚至可能起作用,因为这些状态是彼此相邻的。当你从超级视图中删除它时,它会再次被释放。你的应用程序可能会崩溃。
顺便说一句,顺便说一句,如果没有保留,你根本不应该释放它。或者我错在这里?但是,addSubview应保留它,removeFromSuperview将释放它,因此不需要额外的版本。 Onece删除它应该消失。 (如果不保留在其他地方)