2011-03-29 42 views
0

我已經創建了我自己的scrollView並在該視圖上添加了不同的按鈕。這個類MyScrollView是在ViewController上創建的。然後,我已經在iOS模擬器上測試了它,同時調用了「模擬內存警告」。但沒有任何反應 - 沒有在該MyScrollView上調用dealloc。所以我檢查了不同代碼行上的retaincount。內存管理 - 多個按鈕和retaincount

不幸的是,所有的蘋果內存紀錄和不同的可可博客並沒有幫助我。 因此,這將是冷靜,如果你們中的一些開發者可以幫助我的..

MyScrollView.h

@interface MyScrollView : UIScrollView { 

    NSArray* photosThumb; 
    NSArray* photosFull; 
    NSMutableArray* photoItemsArray; 
} 

@property (nonatomic, retain) NSArray* photosThumb; 
@property (nonatomic, retain) NSArray* photosFull; 
@property (nonatomic, retain) NSMutableArray* photoItemsArray; 

@end 

MyScrollView.m

@implementation MyScrollView 

@synthesize photoItemsArray, photosFull, photosThumb; 

-(id) initArraySmall:(NSArray*) _photos 
     initArrayBig:(NSArray*) _photosBig{ 

     self.photosThumb = _photos; 
     self.photosFull = _photosBig; 

     NSUInteger i, count = [self.photosThumb count]; 

     self.photoItemsArray = [[NSMutableArray alloc] init]; 

     for (i = 0; i < count; i++) 
     {  
      MyButton* photoButton = [[MyButton alloc] init]; 
      NSLog(@"MyButton 1: %d", [photoButton retainCount]); // -> 1 

      [photoButton addTarget:nil action:@selector(buttonDown:) forControlEvents:UIControlEventTouchUpInside];   

      [self.photoItemsArray addObject:photoButton]; 
      NSLog(@"MyButton 2: %d", [photoButton retainCount]); // -> 2 

      [photoButton release]; 
      NSLog(@"MyButton 3: %d", [photoButton retainCount]); // -> 1 

      [self addSubview:[self.photoItemsArray lastObject]]; 
      NSLog(@"MyButton 4: %d", [photoButton retainCount]); // -> 2 
     } 

     [self.photosThumb retain]; 
     [self.photosFull retain]; 
     NSLog(@"photosThumb: %d photosFull: %d", [photosThumb retainCount], [photosFull retainCount]); // -> retaincount 4, 0 


     [self.photoItemsArray release]; 
     NSLog(@"photoItemsArray 1: %d", [self.photoItemsArray retainCount]); // -> 1 


    } 
    return self; 
} 


- (void)dealloc { 
    NSLog(@"dealloc"); 

    self.photosThumb = nil; 
    self.photosFull = nil; 
    self.photoItemsArray = nil; 
    [super dealloc]; 
} 

@end 

Here's我的ViewController.h

@interface VideoViewController : UIViewController { 
    MyScrollView* myView; 
    NSArray* photos; 
    NSArray* photosBig; 
} 
@property (nonatomic, retain) MyScrollView* myView; 
@property (nonatomic, retain) NSArray* photos; 
@property (nonatomic, retain) NSArray* photosBig; 
@end 

ViewController.m

- (void)viewDidLoad { 
    [super viewDidLoad]; 
photos = [NSArray arrayWithObjects:@"one.png", @"two.png", @"three.png", nil]; 
photosBig = [NSArray arrayWithObjects:@"oneBig.png", @"twoBig.png", @"threeBig.png", nil]; 

self.myView = [[MyScrollView alloc] initArraySmall:photos initArrayBig:photosBig]; 
    [self.view addSubview:self.myView]; 
    [self.myView release]; 
} 
- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    NSLog(@"didReceiveMemoryWarning"); 
    [self.myView release]; 
    self.myView = nil; 
} 
- (void)dealloc { 
    [super dealloc]; 
    NSLog(@"dealloc"); 
    [self.photos release]; 
    [self.photosBig release]; 
    [self.photoGallery release]; 
} 
+0

爲什麼你是不是在循環內釋放photoButton ??? – makboney 2011-03-29 12:35:09

+0

@makboney:我在該行之前釋放它:「NSLog(@」MyButton 3:%d「,[photoButton retainCount]); // - > 1 – geforce 2011-03-29 12:52:34

+0

upps抱歉...沒有注意到...一個問題你爲什麼要釋放photoItemsArray ??? – makboney 2011-03-29 12:57:18

回答

0

我覺得你的問題是在dealloc方法。 設置photosThumbphotosFull,並photoItemArray不解除分配的對象。由於您將自定義按鈕添加到數組中,因此必須確保您的每個自定義均已正確釋放。

- (void)dealloc { 
    NSLog(@"dealloc"); 

    self.photosThumb = nil; 
    self.photosFull = nil; 
    self.photoItemsArray = nil; 
    [super dealloc]; 
} 
+0

您好Dimitri,thx爲您的快速回復我也測試過。沒有調用dealloc,MyScrollView類的視圖怎麼樣?所有的按鈕都保留在那裏,所以我必須清理它裏面的東西嗎? – geforce 2011-03-29 12:34:53

+2

你不應該直接調用'dealloc'。允許內存管理系統通過正確使用retain/release來做到這一點。將這些屬性設置爲'nil' **將會釋放它們,所以這是正確的。 – Lauren 2011-03-29 12:34:55

1

MyScrollView很可能仍然由上海華,窗口,響應鏈,等等保留。在您的didReceiveMemoryWarning方法中,您應該撥打[self.myView removeFromSuperview]

前面的答案,然後添加你的代碼的其餘部分:

the documentation

UIKit中提供了幾種方法來獲得較低的內存不足警告,包括以下內容:

  • 執行應用程序委託的方法applicationDidReceiveMemoryWarning:
  • 在您的自定義UIViewController子類中覆蓋didReceiveMemoryWarning方法。
  • 註冊以接收UIApplicationDidReceiveMemoryWarningNotification通知。

我看不出有任何的是,在你的代碼。所以,除非你有其他代碼處理這個問題,模擬一個內存警告將不會對該代碼產生任何影響。

此外,你是過度保留photosThumbphotosFull

0
#import <UIKit/UIKit.h> 

@interface MyScrollView : UIScrollView { 

    NSArray *_photosThumb; //the variables have _ prefix because then you can distinct them from properties 
    NSArray *_photosFull; 
    NSMutableArray *_photoItemsArray; 
} 

@property (nonatomic, retain) NSArray* photosThumb; 
@property (nonatomic, retain) NSArray* photosFull; 
@property (nonatomic, retain) NSMutableArray* photoItemsArray; 

@end 

#import "MyScrollView.h" 


@implementation MyScrollView 

@synthesize photosThumb = _photosThumb; //when you call photosThumb from outside, it returns _photosThumb 
@synthesize photosFull = _photosFull; 
@synthesize photoItemsArray = _photoItemsArray; 

-(id) initArraySmall:(NSArray*) _photos 
     initArrayBig:(NSArray*) _photosBig{ 

    _photosThumb = [[NSArray arrayWithArray: _photos] retain]; // retain > take ownership of the object 
    _photosFull = [[NSArray arrayWithArray: _photosBig] retain]; 

    NSUInteger i, count = [_photosThumb count]; 

    _photoItemsArray = [[NSMutableArray alloc] init]; 

    for (i = 0; i < count; i++) 
    {  
     UIButton* photoButton = [[UIButton alloc] init]; 
     NSLog(@"MyButton 1: %d", [photoButton retainCount]); 

     [photoButton addTarget:nil action:@selector(buttonDown:) forControlEvents:UIControlEventTouchUpInside];   

     [_photoItemsArray addObject:photoButton]; 
     NSLog(@"MyButton 2: %d", [photoButton retainCount]); 

     [photoButton release]; 
     NSLog(@"MyButton 3: %d", [photoButton retainCount]); 

     [self addSubview:[_photoItemsArray lastObject]]; 
     NSLog(@"MyButton 4: %d", [photoButton retainCount]); 
    } 

    NSLog(@"photosThumb: %d photosFull: %d", [_photosThumb retainCount], [_photosFull retainCount]); 

    [_photoItemsArray removeAllObjects]; //this makes sure the array is empty 
    [_photoItemsArray release]; // note: since this is a class variable you should put this in dealloc 
    NSLog(@"photoItemsArray 1: %d", [_photoItemsArray retainCount]); 

    return self; 
} 


- (void)dealloc { 
    NSLog(@"dealloc"); 

    [_photosThumb release]; //release what you "own" 
    [_photosFull release]; 
    /*[_photoItemsArray removeAllObjects]; 
    [_photoItemsArray release];*/ 
    [super dealloc]; 
} 

@end