【问题标题】:UIScrollView PhotoViewer receives memory warning after 125 photos on iPodUIScrollView PhotoViewer 在 iPod 上有 125 张照片后收到内存警告
【发布时间】:2013-02-20 16:19:54
【问题描述】:

我陷入了一个奇怪的问题,试图从所有可能的来源中找到解决方案,但还没有运气。

我的要求类似于 iphone 的 photoviewer 应用程序,但还有更多内容,例如上传图像、下载等。所以从技术上讲,我正在做的是创建一个主滚动视图,其内容大小等于所有选定的图像大小*图像宽度。我在里面有小视图,也等于没有。从选择器中选择的图像。该视图包含一个小的滚动视图和一个允许用户缩放、捏合等的图像视图,主滚动视图具有允许滑动的手势侦听器。 要访问图像,我正在存储资产 URL 并在用户向左或向右滑动时获取图像。在任何时候我只保留 1 张图像是内存,即如果用户滑动到第二张照片,我会从主滚动视图中删除第一张照片。

但如果我选择了 125 张照片并多次滑动以结束并返回,我仍然面临 iPod 上的内存问题。

示例代码:-

    ***//InnerScrollView is the class which contains view with scroll and imageview
    //The values of initial and final counter will always be a diffrence of 1 so it creates only one object**




  for(int j=initialCounter;j<finalCounter;j++) {


            InnerScrollView *innerScrollViewObj=[[InnerScrollView alloc] initWithFrame:CGRectMake(320*j, 0, 320, 480)
                                                                                   url:[selectedImageList objectAtIndex:j] tag:self.initialImageViewCounter];
            innerScrollViewObj.delegate=self;
            [mainScrollView addSubview:innerScrollViewObj];
            [innerScrollViewObj release];
            innerScrollViewObj=nil;
        }

**//This is main scrollview which gets created once**





     mainScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0 , 320, 480)];
        mainScrollView.pagingEnabled = YES;
//        mainScrollView.delegate=self;
        mainScrollView.showsHorizontalScrollIndicator = NO;
        mainScrollView.showsVerticalScrollIndicator = NO;
        mainScrollView.maximumZoomScale = 4.0;
        mainScrollView.minimumZoomScale = 1.0;
        mainScrollView.backgroundColor=[UIColor blackColor];
        [mainScrollView setCanCancelContentTouches:NO];
        mainScrollView.clipsToBounds = YES;
        mainScrollView.scrollEnabled = FALSE;
        mainScrollView.contentSize = CGSizeMake(320*[selectedImageList count], mainScrollView.bounds.size.height);
        [self.view addSubview:mainScrollView];

//THis is the method which gets called when i swipe left and the previous images gets deleted

-(void)deleteScrollViewFormMainView:(NSNumber*)indexToDelete{

    @try{
        NSLog(@"ScrollView to be deleted %@",[[mainScrollView subviews] objectAtIndex:0]);
        [[[mainScrollView subviews] objectAtIndex:0] removeFromSuperview];

    }
    @catch (NSException *e) {
        NSLog(@"ScrollView view exception %@",[e description]);
    }
}






- (id)initWithFrame:(CGRect)frame url :(ALAsset*) imageUrl tag:(int)tag
{
    self = [super initWithFrame:frame];
    if (self) {

        self.userInteractionEnabled=YES;
//        self.tag=tag;
        UIImage *image = [UIImage imageWithCGImage:[[imageUrl defaultRepresentation] fullResolutionImage ]];
        UIImageView* imageview = [[UIImageView alloc] initWithImage:image];
        imageview.tag = VIEW_FOR_ZOOM_TAG;
        imageview.frame=CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
        imageview.backgroundColor=[UIColor clearColor];
        imageview.contentMode=UIViewContentModeScaleAspectFit;

       UIScrollView* pageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
        NSLog(@"Page scrollview is %@",pageScrollView);
        pageScrollView.tag=tag;
        pageScrollView.minimumZoomScale = 0.4f;
        pageScrollView.maximumZoomScale = 2.0f;
        pageScrollView.zoomScale = 1.0f;
        pageScrollView.backgroundColor=[UIColor clearColor];
        pageScrollView.delegate = self;
        pageScrollView.showsHorizontalScrollIndicator = NO;
        pageScrollView.showsVerticalScrollIndicator = NO;
        [pageScrollView setCanCancelContentTouches:NO];
        [self addSubview:pageScrollView];
        [pageScrollView addSubview:imageview];



        UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap)];
        singleTap.numberOfTapsRequired=1;
        singleTap.delegate=self;
        [self addGestureRecognizer:singleTap];
        singleTap=nil;

        UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleDoubleTap)];
        doubleTap.numberOfTapsRequired=2;
        doubleTap.delegate=self;
        [self addGestureRecognizer:doubleTap];

        singleTap=nil;
        doubleTap=nil;
        imageview=nil;
        pageScrollView=nil;

    }
    return self;
}

我应该将 InnerImageView 类设置为单格顿类吗?这会有所帮助吗,因为我认为内存问题可能是因为创建了多个对象(尽管我已正确释放它)。

请大家帮忙!! 提前致谢。

【问题讨论】:

  • 你为什么要使用for 循环来处理你知道只会发生一次的事情?!
  • 那是真的,我会将其移至 if 条件,但我认为这不会导致此问题。对吧?
  • 不,这不会导致您的问题。只是有点尴尬。

标签: iphone objective-c uiscrollview memory-warning photoviewer


【解决方案1】:

你能发布InnerScrollView的定义吗?最可能的问题是您的 delegate 属性是 retain,这会阻止您的 innerScrollViewObj 被释放。

所以,我假设你有类似的东西:

@property (nonatomic, retain) id delegate;

应该是:

@property (nonatomic) id delegate;

或者,如果您启用 ARC,它应该是:

@property (nonatomic, weak) id delegate;

另外,请记住[mainScrollView subviews] 只保存视图,而不保存任何控制器。因此,如果您解除分配控制器,那么它将无法响应任何事件或控制任何内容,并且您可能会由于向解除分配的对象发送消息而出错。

【讨论】:

  • :- 感谢您的回答。我已经修改了内部滚动视图定义的代码。我的委托属性是 @property(assign) id delegate;我不保留代表。
  • :-正确,内部滚动视图是一个视图,所以每当我向左滑动时,我都会删除内部滚动视图的前一个对象,当用户向右滑动时,它会根据位置再次创建对象并显示它,所以我总是有一个可见部分的视图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-28
  • 2012-07-05
  • 2011-04-30
  • 1970-01-01
  • 2015-08-08
  • 1970-01-01
相关资源
最近更新 更多