我懒得在滚动视图中加载图片。但是,当我滚动内容内存分配增加时,它相当缓慢。这是我的代码;
- (void)scrollViewSetUp
{
self.scrollview.delegate = self;
self.automaticallyAdjustsScrollViewInsets = NO;
NSInteger pageCount = self.saleImages.count;
self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0.0,0.0,self.view.frame.size.width,40.0)];
[self.pageControl setNumberOfPages:pageCount];
[self.pageControl setCurrentPage:0];
self.pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
self.pageControl.currentPageIndicatorTintColor = [UIColor whiteColor];
[self.pageControl setBackgroundColor:[UIColor clearColor]];
//Next, you set up the array that holds the UIImageView instances. At first, no pages have been lazily loaded and so you just fill it with the right amount of NSNull objects that are needed – one for each page.
//You’re using [NSNull null] because it’s a lightweight singleton object that can be added to an array to signify a placeholder.
//Later on, you’ll use the fact that there is an NSNull in there to know if that page is loaded or not.
self.pageViews = [[NSMutableArray alloc] init];
for (NSInteger i = 0; i < pageCount; i++) {
[self.pageViews addObject:[NSNull null]];
}
}
这是我的loadPage:
方法;
-(void)loadPage:(NSInteger)page{
if (page < 0 || (page >= self.saleImages.count)) {
//if its outside the range of what you have to display, then do nothing
return;
}
//First, you check if you've already loaded the view. If you haven't, then the object in the pageViews array will be an NSNull ( remember, [NSNull null] is a special singleton which is why == works).
UIView * pageView = [self.pageViews objectAtIndex:page];
if ((NSNull*) pageView == [NSNull null]) {
CGRect frame = self.view.bounds;//set to views bounds instead of scrollviews bounds because it doesnt work very well with autolayout
frame.origin.x = (frame.size.width+kScrollViewPadding) * page;
frame.origin.y = 0.0f;
UIImageView * newPageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[self.saleImages objectAtIndex:page]]];
newPageView.contentMode = UIViewContentModeScaleToFill;
newPageView.frame = CGRectMake(frame.origin.x,frame.origin.y,frame.size.width, frame.size.height);
[self.scrollview addSubview:newPageView];
//Finally, you replace the NSNull in pageViews array with the view you've kust created, so that if this page was asked to load again you would now not go into the if statement and instead do nothing since the view for the page has already been created.
[self.pageViews replaceObjectAtIndex:page withObject:newPageView];
}
}
这是我的purgePage
和loadVisiblePages
;
-(void)purgePage:(NSInteger)page{
if (page <0 || page >= self.saleImages.count) {
//if it's outside the range of what you have to display, then do nothing
return;
}
//Remove a page from the scroll view and reset the container array
UIView * pageView = [self.pageViews objectAtIndex:page];
if ((NSNull *)pageView != [NSNull null]) {
[pageView removeFromSuperview];
pageView = nil;
[self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
}
}
-(void)loadVisiblePages{
//first determine which page is currently visible
CGFloat pageWidth = self.scrollview.frame.size.width;
NSInteger page = (NSInteger)floor((self.scrollview.contentOffset.x * 2.0f + pageWidth)/(pageWidth * 2.0f));
//update the page control
self.pageControl.currentPage = page;
//Work out which pages you want to load
NSInteger firstPage = page -1;
NSInteger lastPage = page+1;
//purge anything before the first page
for (NSInteger i = 0; i<firstPage; i++) {
[self purgePage:i];
}
//load pages in our range
for (NSInteger i = firstPage; i<=lastPage; i++) {
[self loadPage:i];
}
//purge anything after the last page
for (NSInteger i = lastPage +1; i<self.saleImages.count; i++) {
[self purgePage:i];
}
}
我个人觉得我的purgePage
方法有问题。在这里,我从superview中删除pageView并将其设置为nil。我希望有人可以提供帮助,因为我会把头发撕掉。
Generation Analysis
后, 编辑1 似乎UIImage
正在增加。罪魁祸首类是loadPage和loadVisiblePages。
编辑2 @Wain指出imageNamed:
会进行一些缓存。
答案 0 :(得分:2)
您当前正在使用imageNamed:
并缓存已加载的图像以提高性能。这并不总是理想的,您可能需要避免使用这种便捷方法。
为避免使用imageNamed:
,您需要获取图片的路径(可能来自捆绑包),然后使用initWithContentsOfFile:
。
请注意,删除所有缓存可能过于极端,您可能希望创建自己的缓存(例如使用字典),您可以在其中控制一次缓存多少图像。此外,根据您显示图像的方式,您可能需要在应用中添加一些不同尺寸的图像,以便为每种情况加载最合适的尺寸。
另请注意,如果需要,可以在后台加载图像,然后将图像推送到主线程以更新UI。