开发者

Memory Management - Multiple Buttons and retaincount

i´ve created my own scrollView and added different Buttons on that View. This class MyScrollView was created on a ViewController. Then i´ve tested that on the iOS simulator while calling the "simulate memory warning". But nothing happens - no dealloc on that MyScrollView is called. So i´ve checked the retaincount on different code lines.

Unfortunately, all the apple memory docu and different cocoa blogs didn´t help me. So it would be cool if some of you devs could help me on that..

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 my 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];
}


Your MyScrollView is likely still retained by the superview, window, responder chain, etcetera. In your didReceiveMemoryWarning method you should call [self.myView removeFromSuperview].

Previous answer, before you added the rest of your code:

From the documentation:

UIKit provides several ways to receive low-memory warnings, including the following:

  • Implement the applicationDidReceiveMemoryWarning: method of your application delegate.
  • Override the didReceiveMemoryWarning method in your custom UIViewController subclass.
  • Register to receive the UIApplicationDidReceiveMemoryWarningNotification notification.

I don't see any of that in your code. So, unless you have other code where this is dealt with, simulating a memory warning won't have any effect with that code.

Additionally, you are over-retaining both photosThumb and photosFull.


I think your problem is in the dealloc method. Setting photosThumb, photosFull, and photoItemArray as nil do not deallocate the objects. Since, you add custom Button to the arrays, you must make sure that each of your custom are properly deallocated.

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

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


#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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜