【问题标题】:Xcode: UIScrollView image gallery, having memory problemsXcode:UIScrollView 图片库,有内存问题
【发布时间】:2011-01-18 16:38:43
【问题描述】:

我正在尝试开发基于UIScrollView 的图片库。

所以让我解释一下我在这里想要实现的目标:

我想要一个滑动演示,最多可以显示 140 张图像。 (您可以来回滑动) 我在网上找到了信息,有人告诉我最好的方法是使用 UIScrollview,它有 3 个 UIImageViews,您可以创建并从 superview 中删除。

所以我在一些教程的帮助下设法创建了这样一个“滑动图片库”:)。 我已成功将应用程序上传到 ipad,启动应用程序并运行它。

在我查看了大约 50-70 张幻灯片后,应用程序崩溃(内存不足)。我对 Obj 的了解。 C 不是那么好。

您会在下面找到代码:它 Prob.与发布图像有关。 对代码的改进会很有帮助

#import "ParatelPresentationViewController.h"

//Define the UIView ( we need 3 Image Views left, mid right);
@interface SlideShowView : UIView
{
 NSArray * mImages;

 UIImageView * mLeftImageView;
 UIImageView * mCurrentImageView;
 UIImageView * mRightImageView;

 NSUInteger mCurrentImage;

 BOOL mSwiping;
 CGFloat mSwipeStart;
}

- (id)initWithImages:(NSArray *)inImages;

@end // SlideShowView

#pragma mark -

@implementation SlideShowView


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

- (id)initWithImages:(NSArray *)inImages
{
 if (self = [super initWithFrame:CGRectZero])
 {
  mImages = [inImages retain];

  NSUInteger imageCount = [inImages count];
  NSLog(@"hoeveel foto's: %i");
  if (imageCount > 0)
  {
   mCurrentImageView = [self createImageView:0];
   [self addSubview:mCurrentImageView];

   if (imageCount > 1)
   {
    mRightImageView = [self createImageView:1];
    [self addSubview:mRightImageView];
   }

  }

  self.opaque = YES;
  self.backgroundColor = [UIColor blueColor];
  self.contentMode = UIViewContentModeScaleAspectFit;
  self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
 }

 return self;
}

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



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

 //CGSize contentSize = self.frame.size; // Enable when you use content.width/height
 //self.backgroundColor = [UIColor redColor];
 mLeftImageView.frame = CGRectMake(-1024, 0.0f, 1024, 748);//  (-1024, 0.0f, 1024, 748) can be replaced by  (-contentSize.width, 0.0f, contentSize.width, contentSize.height);
 mCurrentImageView.frame = CGRectMake(0.0f, 0.0f, 1024, 748);
 mRightImageView.frame = CGRectMake(1024, 0.0f,  1024, 748);
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
 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 - 1024, 0.0f, 1024, 748);
 mCurrentImageView.frame = CGRectMake(swipeDistance, 0.0f, 1024, 748);
 mRightImageView.frame = CGRectMake(swipeDistance + 1024, 0.0f, 1024, 748);
}

- (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.image = nil;
  //[mRightImageView.image release];
  [mRightImageView removeFromSuperview];
  [mRightImageView release];
  //mRightImageView = nil;
  //NSLog(@"Count of mRight : %i",[mRightImageView retainCount]);


  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.image = nil;
  //[mLeftImageView.image release];
  [mLeftImageView removeFromSuperview];
  [mLeftImageView release];
  //mLeftImageView = nil;

  mLeftImageView = mCurrentImageView;
  mCurrentImageView = mRightImageView;

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

   [self addSubview:mRightImageView];
   NSLog(@"Count of mRight : %i",[mRightImageView.image retainCount]);
  }
  else
  {
   mRightImageView = nil;
  }
 }

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

 mLeftImageView.frame = CGRectMake(-1024, 0.0f, 1024, 748);
 mCurrentImageView.frame = CGRectMake(0.0f, 0.0f, 1024, 748);
 mRightImageView.frame = CGRectMake(1024, 0.0f, 1024, 748);

 [UIView commitAnimations];

 mSwiping = NO;
}


@end // SlideShowView


#pragma mark -


@implementation ParatelPresentationViewController

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

  NSMutableArray *Displayimages = [[NSMutableArray alloc]init];
  int i;
  for(i=0 ; i<139 ; i++) {


   NSString *tempString = [NSString stringWithFormat:@"Dia%d", i+1];
   NSLog(@"Dia%d.jpg", i+1);
   NSString *imageFile = [[NSBundle mainBundle] pathForResource:tempString ofType:@"JPG"];
   BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:imageFile];

   if (fileExists){
    [Displayimages addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:tempString ofType:@"JPG"]]];
    NSLog(@"img");
   }else {
    break;
   }

  }


  //NSArray * images = [NSArray arrayWithObjects:[UIImage imageNamed:@"1.jpg"], [UIImage imageNamed:@"2.jpg"], [UIImage imageNamed:@"3.jpg"], [UIImage imageNamed:@"4.jpg"], [UIImage imageNamed:@"5.jpg"], nil];
  //NSLog(@"Objects Img = %@", images);
  NSLog(@"Images %@",Displayimages);
  self.view = [[[SlideShowView alloc] initWithImages:Displayimages] autorelease];
  [Displayimages release];
 }

 return self;
}

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    //return YES;
 return UIInterfaceOrientationIsLandscape (interfaceOrientation);

}

@end

如果您能找到解决方案或提示,欢迎大家!

提前致谢

亲切的问候巴特!

【问题讨论】:

  • 你可以只更改 UIImageView 的image 字段,而不是发布和创建新的。
  • Xcode 中的静态分析器是捕获此类内存泄漏的绝佳工具。在 Xcode 4 中,您可以通过转到产品菜单并选择分析来运行它。
  • 你应该使用 UICollectionView 来显示图像。它提供了可重用的视图,并且并非所有图像都需要一次加载到内存中。

标签: iphone xcode uiscrollview


【解决方案1】:

你肯定在 createImageView: 中有内存泄漏。你将不得不改变

return result;

return [result autorelease];

可能会有更多泄漏,但这是显而易见的。

  • 约翰内斯

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多