2011-03-01 33 views
0

參照這個頁面控制的例子可能有人請解釋代碼流?樂器在這裏給我泄漏,所以尋找一些幫助。可能在這個例子中解釋代碼流?內存泄漏?哪裏?

回覆:本教程: http://www.edumobile.org/iphone/iphone-programming-tutorials/pagecontrol-example-in-iphone/

我們初始化數組爲NULL我們AppDidFinishLaunching方法的對象......

NSMutableArray *controllers = [[NSMutableArray alloc] init]; 
for (unsigned i = 0; i < kNumberOfPages; i++) { 
    [controllers addObject:[NSNull null]]; 
} 
self.viewControllers = controllers; 
[controllers release]; 

,然後調用:

[self loadScrollViewWithPage:0]; 
[self loadScrollViewWithPage:1]; 

這裏是實施loadScrollViewWithPage

- (void)loadScrollViewWithPage:(int)page { 
if (page < 0) return; 
if (page >= kNumberOfPages) return; 

PageControlExampleViewControl *controller = [viewControllers objectAtIndex:page]; 
if ((NSNull *)controller == [NSNull null]) { 
    controller = [[PageControlExampleViewControl alloc] initWithPageNumber:page]; 
    [viewControllers replaceObjectAtIndex:page withObject:controller]; 
    [controller release]; 
} 

if (nil == controller.view.superview) { 
    CGRect frame = scrollView.frame; 
    frame.origin.x = frame.size.width * page; 
    frame.origin.y = 0; 
    controller.view.frame = frame; 
    [scrollView addSubview:controller.view]; 
} 
} 

儀器是給我一個泄漏以下行此實現:

如果(零== controller.view.superview){

任何人都知道爲什麼,這將是一個報道儀器泄漏?我的代碼是相同的。 也在初始調用後[self loadScrollViewWithPage:0];,第一次通過並創建對象,BOTH如果條款已通過並進入。

這怎麼可能? 如果我們輸入第一個如果條款,我們分配並創建我們的控制器,並通過**釋放*它([控制器發佈])結束。

應該不是下一行(如果(零== controller.view.superview))生產,因爲我們剛剛發佈了上述控制器的EXC_BAD_ACCESS錯誤看見了什麼?

屏幕截圖FROM INSTRUMENTS: Instruments screenshot

回答

1

我不知道爲什麼儀器會報告該行的泄漏,除非它只是注意到controller.view是由該行分配的(訪問UIViewController的視圖屬性會自動加載視圖,如果有必要)還沒有被釋放(它不應該像scrollView一樣存在,controller.view仍然是子視圖)。

這是正確的,它通過if條款。第一個if檢查該頁面索引是否實際存在視圖控制器,如果不存在,則創建一個(但不會將其添加到scrollView)。第二個檢查頁面索引的視圖控制器的視圖是否已經添加到scrollView,如果沒有,則添加它。

它不會崩潰的原因是因爲[viewControllers replaceObjectAtIndex:page withObject:controller]將控制器添加到保留控制器的NSMutableArray。它可能會略有減少混亂,像這樣做,而不是:

if ((NSNull *)controller == [NSNull null]) { 
    controller = [[[PageControlExampleViewControl alloc] initWithPageNumber:page] autorelease]; 
    [viewControllers replaceObjectAtIndex:page withObject:controller]; 
} 
+0

爲受影響的行添加了樂器輸出的屏幕截圖。就像你說的那樣,我真的不知道爲什麼這會漏水。在它正在泄漏的線雖然_controller.view_是**不是**滾動視圖的子視圖呢?它將它添加到它即將進入的子句中? – 2011-03-01 18:38:34

+0

從你的截圖中,它抱怨分配的視圖。報告泄漏的行是分配視圖之前程序中的最後一行。你在某個時候漏了scrollView嗎?這可能會導致Instruments將其所有子視圖計數爲泄漏。 – Anomie 2011-03-01 19:12:15

0

在我看來,你是不是正確地釋放滾動視圖。

0

這怎麼可能?如果我們輸入第一個if子句,我們分配並創建我們的控制器,並以*釋放它([控制器釋放])結束。

不應該在下一行(if(nil == controller.view.superview))產生一個EXC_BAD_ACCESS錯誤,因爲我們剛剛發佈了RELEASED控制器?

看看alloc和release之間的界限。

[viewControllers replaceObjectAtIndex:page withObject:controller]; 

viewControllers數組將保留控制器。

但是,這不是好代碼。正是你所說的原因。一見不見。

+0

我的理解是,viewControllers將保留的ViewController肯定的,但自從_ [控制器發佈] _,它應該不再是通過訪問*控制器指針應該如何?只能通過[viewControllers objectAtIndex:page]? – 2011-03-01 17:23:06

+0

當一個對象被保留時,它在內存中的位置保持不變。控制器指針仍然引用內存中的相同地址。一個版本不會改變指針和對象的地址。這就是爲什麼我們得到所有BAD_ACCESS錯誤。 – 2011-03-01 17:27:00

+0

所以是_ [controller] _ release調用是多餘的並且不必要,因爲我們通過將對象放入數組來保留對象? – 2011-03-01 17:36:42