开发者

A problem with release object

here my code

- (UIImageView *)createImageView:(NSUInteger)inImageIndex
{   
    UIImageView * result = [[UIImageView alloc] initWithImage:[mImages objectAtIndex:inImageIndex]];
    result.opaque = YES;
    result.userInteractionEnabled = NO;
    result.backgroundColor = [UIColor blackColor];
    result.contentMode = UIViewContentModeScaleAspectFit;
    result.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    return [result autorelease];
}

this method will call by init 3 times but not error when i try to swipe image this method will call again and got some error

objc[962]: FREED(id): message release sent to freed object=0x3b37860

Note: if i not release result it will not error but i will get some memory leak

how can i fix it?

- (id)initWithImages:(NSMutableArray *)inImages byIndex:(int)Index
{
    PictureCell* data = [PictureCell alloc];
    NSLog(@"get index = %d", [data getIndex]);
    int cellIndex = [data getIndex];
    mCurrentImage = Index * 3 + cellIndex;
    Index = mCurrentImage;

    if (self = [super initWithFrame:CGRectZero])
    {
        mImages = [inImages retain];
        NSUInteger imageCount = [inImages count];
        if (Index == 0) {
            mCurrentImageView = [self createImageView:0];
            [self addSubview:mCurrentImageView];
            mRightImageView = [self createImageView:1];
            [self addSubview:mRightImageView];

        }
        else if (Index == (imageCount-1)) {
            mCurrentImageView = [self createImageView:imageCount-1];
            [self addSubview:mCurrentImageView];
            mLeftImageView = [self createImageView:(imageCount-2)];
            [self addSubview:mLeftImageView];

        }
        else {
            mLeftImageView = [self createImageView:(Index-1)];
            [self addSubview:mLeftImageView];

            mCurrentImageView = [self createImageView:Index];
            [self addSubview:mCurrentImageView];

            mRightImageView = [self createImageView:(Index+1)];
            [self addSubview:mRightImageView];

        }
        self.opaque = YES;
        self.backgroundColor = [UIColor blackColor];
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    }
    [data autorelease];
    return self;
}

here is create array from another class and send to mImages = [inImages retain]

NSMutableArray *images = [NSMutableArray arrayWithObjects:[UIImage imageNamed:@"JGirl 01.jpg"],
[UIImage imageNamed:@"JGirl 03.jpg"],[UIImage imageNamed:@"JGirl 04.jpg"],[UIImage imageNamed:@"JGirl 05.jpg"],[UIImage imageNamed:@"JGirl 06.jpg开发者_运维问答"],[UIImage imageNamed:@"JGirl 07.jpg"],nil];

self.view = [[[SlideShowView alloc] initWithImages:images byIndex:index] autorelease];

Full Code

static NSUInteger mCurrentImage;
static NSString *title[] = {
    @"JGirl 01.jpg",
    @"JGirl 03.jpg",
    @"JGirl 04.jpg",
    @"JGirl 05.jpg",
    @"JGirl 06.jpg",
    @"JGirl 07.jpg",
    @"JGirl 08.jpg",
    @"JGirl 09.jpg",
    @"JGirl 10.jpg",
};

static BOOL toggle = YES;
@implementation SlideShowView
@synthesize AppDelegate;

- (UIImageView *)createImageView:(NSUInteger)inImageIndex
{
    if (inImageIndex >= [mImages count])
    {
        return nil;
    }

    UIImageView * result = [[UIImageView alloc] initWithImage:[mImages objectAtIndex:inImageIndex]];
    result.opaque = YES;
    result.userInteractionEnabled = NO;
    result.backgroundColor = [UIColor blackColor];
    result.contentMode = UIViewContentModeScaleAspectFit;
    result.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    return [result autorelease];
}

- (id)initWithImages:(NSMutableArray *)inImages byIndex:(int)Index
{
    PictureCell* data = [PictureCell alloc];
    NSLog(@"get index = %d", [data getIndex]);
    int cellIndex = [data getIndex];
    mCurrentImage = Index * 3 + cellIndex;
    Index = mCurrentImage;

    if (self = [super initWithFrame:CGRectZero])
    {
        mImages = [inImages retain];

        NSUInteger imageCount = [inImages count];

        if (Index == 0) {
            mCurrentImageView = [self createImageView:0];
            [self addSubview:mCurrentImageView];
            mRightImageView = [self createImageView:1];
            [self addSubview:mRightImageView];

        }
        else if (Index == (imageCount-1)) {
            mCurrentImageView = [self createImageView:imageCount-1];
            [self addSubview:mCurrentImageView];
            mLeftImageView = [self createImageView:(imageCount-2)];
            [self addSubview:mLeftImageView];

        }
        else {
            mLeftImageView = [self createImageView:(Index-1)];
            [self addSubview:mLeftImageView];

            mCurrentImageView = [self createImageView:Index];
            [self addSubview:mCurrentImageView];

            mRightImageView = [self createImageView:(Index+1)];
            [self addSubview:mRightImageView];

        }
        self.opaque = YES;
        self.backgroundColor = [UIColor blackColor];
        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    }
    [data autorelease];
    return self;
}

- (void)dealloc
{
    [mImages release];
    [AppDelegate release];
    [super dealloc];
}



- (void)layoutSubviews
{
    if (mSwiping)
        return;

    CGSize contentSize = self.frame.size;
    mLeftImageView.frame = CGRectMake(-contentSize.width, 0.0f, contentSize.width, contentSize.height);
    mCurrentImageView.frame = CGRectMake(0.0f, 0.0f, contentSize.width, contentSize.height);
    mRightImageView.frame = CGRectMake(contentSize.width, 0.0f, contentSize.width, contentSize.height);
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    NSUInteger tapCount = [touch tapCount];
    switch (tapCount) {
        case 2:
        {
            AppDelegate = [[UIApplication sharedApplication] delegate];
            if (toggle) {
                [AppDelegate.navigationController setNavigationBarHidden:YES animated:YES];
            }
            else {
                [AppDelegate.navigationController setNavigationBarHidden:NO animated:YES];
            }

            toggle = !toggle;
            break;
        }
        default:
            break;
    }

    NSLog(@"touches count = %d  and Tap count = %d  from slide show view toggle is %i",[touches count], tapCount,toggle);

    if ([touches count] != 1)
        return;

    mSwipeStart = [[touches anyObject] locationInView:self].x;
    mSwiping = YES;

    mLeftImageView.hidden = NO;
    mCurrentImageView.hidden = NO;
    mRightImageView.hidden = NO;

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (! mSwiping || [touches count] != 1)
        return;

    CGFloat swipeDistance = [[touches anyObject] locationInView:self].x - mSwipeStart;

    CGSize contentSize = self.frame.size;

    mLeftImageView.frame = CGRectMake(swipeDistance - contentSize.width, 0.0f, contentSize.width, contentSize.height);
    mCurrentImageView.frame = CGRectMake(swipeDistance, 0.0f, contentSize.width, contentSize.height);
    mRightImageView.frame = CGRectMake(swipeDistance + contentSize.width, 0.0f, contentSize.width, contentSize.height);
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (! mSwiping)
    {
        return;
    }

    CGSize contentSize = self.frame.size;

    NSUInteger count = [mImages count];

    CGFloat swipeDistance = [[touches anyObject] locationInView:self].x - mSwipeStart;
    if (mCurrentImage > 0 && swipeDistance > 50.0f)
    {
        [mRightImageView removeFromSuperview];
        [mRightImageView release];

        mRightImageView = mCurrentImageView;
        mCurrentImageView = mLeftImageView;

        mCurrentImage--;
        if (mCurrentImage > 0)
        {
            mLeftImageView = [self createImageView:mCurrentImage - 1];
            mLeftImageView.hidden = YES;

            [self addSubview:mLeftImageView];
        }
        else
        {
            mLeftImageView = nil;
        }
    }
    else if (mCurrentImage < count - 1 && swipeDistance < -50.0f)
    {
        [mLeftImageView removeFromSuperview];
        [mLeftImageView release];

        mLeftImageView = mCurrentImageView;
        mCurrentImageView = mRightImageView;

        mCurrentImage++;
        if (mCurrentImage < count - 1)
        {
            mRightImageView = [self createImageView:mCurrentImage + 1];
            mRightImageView.hidden = YES;

            [self addSubview:mRightImageView];
        }
        else
        {
            mRightImageView = nil;
        }
    }

    [UIView beginAnimations:@"swipe" context:NULL];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
    [UIView setAnimationDuration:0.3f];

    mLeftImageView.frame = CGRectMake(-contentSize.width, 0.0f, contentSize.width, contentSize.height);
    mCurrentImageView.frame = CGRectMake(0.0f, 0.0f, contentSize.width, contentSize.height);
    mRightImageView.frame = CGRectMake(contentSize.width, 0.0f, contentSize.width, contentSize.height);
    mSwiping = NO;
    [UIView commitAnimations];

}


@end // SlideShowView

@implementation SlideShowViewController
@synthesize contentView;

- (id)init:(int) index
{
    if (self = [super initWithNibName:nil bundle:nil])
    { 

        NSMutableArray *images = [NSMutableArray arrayWithObjects:
                            [UIImage imageNamed:@"JGirl 01.jpg"],
                            [UIImage imageNamed:@"JGirl 03.jpg"],
                            [UIImage imageNamed:@"JGirl 04.jpg"],
                            [UIImage imageNamed:@"JGirl 05.jpg"],
                            [UIImage imageNamed:@"JGirl 06.jpg"],
                            [UIImage imageNamed:@"JGirl 07.jpg"],
                            [UIImage imageNamed:@"JGirl 08.jpg"],
                            [UIImage imageNamed:@"JGirl 09.jpg"],
                            [UIImage imageNamed:@"JGirl 10.jpg"],nil
                            ];


        self.view = [[[SlideShowView alloc] initWithImages:images byIndex:index] autorelease];  

        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];

        button.frame = CGRectMake(100, 0, 100, 30);
        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(save)];

    }

    return self;
}

- (void)loadView
{

}

- (void)viewWillAppear:(BOOL)animated
{
    NSLog(@"mCurrentImage %d",mCurrentImage);

}

- (void)save
{
    NSLog(@"save clicked");
    UIImage *img = [UIImage imageNamed:title[mCurrentImage]];
    UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), self);

    [img release];
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    NSString *str = @"Wallpaper saved in Photo Albums successfully. Hit the Home Button and open Photo, select the wallpaper and chose the function Set as Use as Wallpaper.";
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Saved." message:str delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alert show];
}


@end


UPDATE: You should not be releasing the AppDelegate variable because you never retain the instance, you just assign it

Could you show the dealloc method for the class which you have showed the init method for?

  • mCurrentImageView
  • mRightImageView
  • mLeftImageView

Are instance variables and you are assigning autoreleased objects to them. If you are also releasing these ivars in your dealloc method you would be double releasing

I can actually tell you now that the correct way to handle this is

mCurrentImageView = [[self createImageView:0] retain];

Since you're assigning those to the ivars you want to make sure you hold on to them until you're done.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜