进入公司做程序也有些日子了吧,做程序多少也有了些感受,真想全部都记下来,可是不行啊,人太懒了。没那个恒心。不聊那些没边得话题了,还说来说我们的内存吧。
记得还在那被人们奉为圣殿的大学校园里混时,老师常给我们说编程有很多要学的东西,什么内存的分配使用,算法问题等等一系列。但是同时也说道,现在的硬件处理能力已经很强了,内存问题一般都是够用了的。所以现在内存什么的,只要我们做到了分配后需要释放的我们保证了释放就不会存在问题,也许这对多数的编程来说是真的,但是此刻我感觉好像是被忽悠了。
先不谈这些,还是从自己做的事儿谈起吧,这里不得不先说明了,自己是做手机应用的iphone手机上的应用,或许说道iphone手机,很多人都会觉得他的画面处理效果确实很不错。不过我们这里也不谈这个问题,这里只是想说从iphone 1代到现在的4代,对开发的应用程序使用的内存的限制是不一样的,而这里要讨论的就是做满足iphone 4代品质的应用程序在iphone 3上进行测试。而这里最大的问题就在于图片资源的问题了,对于iphone 4其满屏像素是640*960,而其他几代的满屏像素都是320*480,这样满足iphone 4的图片资源要比iphone 3的图片资源大上4倍了,与此同时,由于iphone 3能够供没个应用程序使用的内存本身限制,所以对内存问题就是一个不得不考虑的问题了。当然,这里要考虑的不仅仅是内存的分配和释放问题,还包括处理的方式问题了。
谈到这里还是用个例子来说说吧,在iphone提供的类中有一个UIScrollView类,这个类主要用于滑动效果。我们先看下面这端代码吧,如果仅仅从技术实现的角度来看,是不应该有什么问题的,然而在若是在iphone 3代装载就会出问题。这里的问题就在于我们加载进去的图片资源太多(9张),我们可以计算一下对于9张640*960的图片大小:640*960*4 = 2457600 = 2400k = 2.34375M,然后在乘9张 = 21.09375M,如此大的一个内存使用量在iphone 3代中的应用程序是绝对不允许的。所以程序崩溃就不足为奇了。
UIWindow *tmpWindow = [[UIApplication sharedApplication] keyWindow];
CGFloat rate = tmpWindow.frame.size.width/640;
self.navigationController.navigationBarHidden = YES;
NSArray *listArr = [[NSArray alloc] initWithObjects:@"yoga001",@"yoga002",
@"yoga003",@"yoga004",@"yoga005",@"yoga006",
@"yoga007",@"yoga008",@"yoga009",
nil];
NSInteger tmpCount = [listArr count];
m_scrollView.contentSize = CGSizeMake(640*rate*tmpCount, 960*rate);
for (NSInteger i = 0; i < tmpCount; i++) {
UIImageView *tmpImageView = [[UIImageView alloc] initWithFrame:
CGRectMake(640*rate*i, 0, 640*rate, 960*rate)];
tmpImageView.tag = 100+i;
NSString *tmpStr = [NSString stringWithFormat:@"fxjyogapic%d.png",i+1];
tmpImageView.image = [UIImage imageWithContentsOfFile:BUNDLE_PATH(tmpStr)];
[m_scrollView addSubview:tmpImageView];
[tmpImageView release];
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(30*rate+640*rate*i, 600*rate, 584*rate, 346*rate)];
textView.tag = 200+i;
textView.editable = NO;
textView.backgroundColor = [UIColor clearColor];
textView.font = [UIFont systemFontOfSize:32*rate];
textView.textColor = [UIColor whiteColor];
textView.text = NSLocalizedString([listArr objectAtIndex:i],@"");
[m_scrollView addSubview:textView];
[textView release];
}
[listArr release];
既然遇到问题了,那么我们很自然就必须解决了,我们再来看看下面的程序
UIWindow *tmpWindow = [[UIApplication sharedApplication] keyWindow];
CGFloat rate = tmpWindow.frame.size.width/640;
NSArray *listArr = [[NSArray alloc] initWithObjects:@"yoga001",@"yoga002",
@"yoga003",@"yoga004",@"yoga005",@"yoga006",
@"yoga007",@"yoga008",@"yoga009",
nil];
NSInteger tmpCount = [listArr count];
m_scrollView.contentSize = CGSizeMake(640*rate*tmpCount, 960*rate);
for (NSInteger i = 0; i < tmpCount; i++) {
UIImageView *tmpImageView = [[UIImageView alloc] initWithFrame:
CGRectMake(640*rate*i, 0, 640*rate, 960*rate)];
tmpImageView.tag = 100+i;
[m_scrollView addSubview:tmpImageView];
[tmpImageView release];
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(30*rate+640*rate*i, 600*rate, 584*rate, 346*rate)];
textView.tag = 200+i;
textView.editable = NO;
textView.backgroundColor = [UIColor clearColor];
textView.font = [UIFont systemFontOfSize:32*rate];
textView.textColor = [UIColor whiteColor];
textView.text = NSLocalizedString([listArr objectAtIndex:i],@"");
[m_scrollView addSubview:textView];
[textView release];
}
[listArr release];
m_scrollView.contentOffset = CGPointMake(0, 0);
UIImageView *currentView = (UIImageView *)[m_scrollView viewWithTag:100];
currentView.image = [UIImage imageWithContentsOfFile:BUNDLE_PATH(@"fxjyogapic1.png")];
在这个过程中我们只加载了其中一张,当然占用的内存少了。很自然程序能够正常运行了,不过我们这里有了另外一个问题,就是我们必须实现滑动效果,怎么办呢?还好UIScrollView有个代理叫做UIScrollViewDelegate能帮我们做一些事,我们就看看下面的代码了。
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
NSInteger currentPage = (NSInteger)(scrollView.contentOffset.x/320);
NSLog(@"Begin : currentPage = %d",currentPage);
if (currentPage <= 0) {
UIImageView *nextImageView = (UIImageView *)[m_scrollView viewWithTag:101];
nextImageView.image = [UIImage imageWithContentsOfFile:BUNDLE_PATH(@"fxjyogapic2.png")];
//nextImageView.image = [UIImage imageNamed:@"fxjofficeExciresebg2.png"];
} else if (currentPage >= 8) {
UIImageView *lastImageView = (UIImageView *)[m_scrollView viewWithTag:107];
lastImageView.image = [UIImage imageWithContentsOfFile:BUNDLE_PATH(@"fxjyogapic8.png")];
//lastImageView.image = [UIImage imageNamed:@"fxjofficeExciresebg8.png"];
} else {
UIImageView *lastImageView = (UIImageView *)[m_scrollView viewWithTag:100+currentPage-1];
NSString *tmpStr = [NSString stringWithFormat:@"fxjyogapic%d.png",currentPage];
lastImageView.image = [UIImage imageWithContentsOfFile:BUNDLE_PATH(tmpStr)];
//lastImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"fxjofficeExciresebg%d.png",currentPage]];
UIImageView *nextImageView = (UIImageView *)[m_scrollView viewWithTag:100+currentPage+1];
NSString *tmpStr1 = [NSString stringWithFormat:@"fxjyogapic%d.png",currentPage+2];
nextImageView.image = [UIImage imageWithContentsOfFile:BUNDLE_PATH(tmpStr1)];
//nextImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"fxjofficeExciresebg%d.png",currentPage+2]];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
NSInteger currentPage = (NSInteger)(scrollView.contentOffset.x/320);
NSLog(@"End : currentPage = %d",currentPage);
for (NSInteger i = 0; i < 9; i++) {
if (i != currentPage) {
UIImageView *otherImageView = (UIImageView *)[m_scrollView viewWithTag:100+i];
otherImageView.image = nil;
}
}
UIImageView *currentView = (UIImageView *)[m_scrollView viewWithTag:100+currentPage];
if (currentView.image == nil) {
NSString *tmpStr = [NSString stringWithFormat:@"fxjyogapic%d.png",currentPage+1];
currentView.image = [UIImage imageWithContentsOfFile:BUNDLE_PATH(tmpStr)];
//currentView.image = [UIImage imageNamed:[NSString stringWithFormat:@"fxjofficeExciresebg%d.png",currentPage+1]];
}
}
通过实现的两个方式,我们的问题得到了解决,但是这里还是给我们遗留下了一个问题,由于处理速度问题,滑动效果的流畅程度自然会有所降低了,所谓有得必有失嘛。
写这些,只是想说名一点,内存问题真的会让我们感觉到头疼,他也不仅仅是一个分配和释放问题,也涉及到我们的程序实现方式和其他要求限制问题。在内存问题上,有些问题是不太确定的,或许我们采用的方式不同,将会有不同的效果。