发布对象的问题

时间:2009-11-19 10:50:34

标签: iphone memory-management

这里是我的代码

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

此方法将通过init调用3次但不会出错 当我尝试滑动图像时,此方法将再次调用并出现一些错误

objc [962]:FREED(id):发送给释放对象的消息发布= 0x3b37860

注意:如果我没有发布结果,它不会出错但我会得到一些内存泄漏

我该如何解决?

- (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;
}

这里是从另一个类创建数组并发送到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];

完整代码

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

1 个答案:

答案 0 :(得分:0)

UPDATE:你不应该发布AppDelegate变量,因为你从不保留实例,你只需要分配它

你能为你展示了init方法的类显示dealloc方法吗?

  • mCurrentImageView
  • mRightImageView
  • mLeftImageView

是实例变量,并且您正在为它们分配自动释放的对象。如果您也在dealloc方法中释放这些ivars,那么您将会双重释放

我现在可以告诉你,处理这个问题的正确方法是

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

由于您要将这些分配给ivars,因此您需要确保在完成之前保留它们。