在我的应用程序中,我使用 UIImageView 和 UIScrollView 来显示很多图像(每次大约有 20 张图像,每张图像大约 600px*500px 和大小大约 600kb)。
我使用这段代码来完成这个功能:
// Here is pictures Data;
self.klpArry = self.pictureData;
CGSize size = self.klpScrollView1.frame.size;
for (int i=0; i < [klpArr count]; i++) {
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake((size.width * i)+300, 20, 546, 546)];
NSString *filePath = [[NSBundle mainBundle] pathForResource:[klpArr objectAtIndex:i] ofType:@"jpg"];
UIImage *imageData = [[UIImage alloc]initWithData:[NSData dataWithContentsOfFile:filePath]];
[iv setImage:imageData];
iv.backgroundColor = [UIColor grayColor];
[self.klpScrollView1 addSubview:iv];
imageData = nil;
iv = nil;
iv.image = nil;
filePath = nil;
[imageData release];
[filePath release];
[iv release];
}
// show the picture in scrollview;
[self.klpScrollView1 setContentSize:CGSizeMake(size.width * numImage, size.height)];
self.klpScrollView1.pagingEnabled = YES;
self.klpScrollView1.showsHorizontalScrollIndicator = NO;
self.klpScrollView1.backgroundColor = [UIColor grayColor];
但是每次我初始化这个函数,内存都会增加大约5MB。实际上我发布了 UIImageView, UIimage 和 UIScrollView (vi.image=nil, [vi release]) 但它不起作用,分配的内存没有被释放。顺便说一句,我先用了我 friend 的代码 vi.image = nil 然后 vi = nil; 但是图片没有显示在 ScrollView 上。
最佳答案
在我看来,主要问题是您将局部变量设置为 nil然后您继续尝试在 release 等方法中使用这些局部变量等等,但因为它们已被设置为 nil ,这些方法现在什么都不做,而带有 +1 retainCount 的对象(或现在 +2,因为您已将它们添加到您的 View 中)永远不会发布。
因此,我建议如下:
//Here is pictures Data;
self.klpArry = self.pictureData;
CGSize size = self.klpScrollView1.frame.size;
for (int i=0; i < [klpArr count]; i++) {
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake((size.width * i)+300, 20, 546, 546)];
NSString *filePath = [[NSBundle mainBundle] pathForResource:[klpArr objectAtIndex:i] ofType:@"jpg"];
UIImage *imageData = [[UIImage alloc]initWithData:[NSData dataWithContentsOfFile:filePath]];
[iv setImage:imageData];
iv.backgroundColor = [UIColor grayColor];
[self.klpScrollView1 addSubview:iv];
// Don't set these to nil, or else subsequent release statements do nothing!
// These statements are actually not necessary because they refer to local
// variables so you don't need to worry about dangling pointers. Make sure
// you're not confusing the purpose of setting a pointer to nil in ARC to
// what you're doing in your non-ARC code.
//
// imageData = nil;
// iv = nil;
// You don't want to set this to nil because if iv is not nil, your image
// will be removed from your imageview. So, not only is this not needed,
// but it's undesired.
//
// iv.image = nil;
// This statement is not necessary for the same reason you don't do it
// to imageData or iv, either. This is probably even worse, though, because
// filePath is not a variable that you initialized via alloc. You should
// only be releasing things you created with alloc (or new, copy, mutableCopy,
// for which you issued a retain statement).
//
// filePath = nil;
[imageData release];
// filePath is a +0 retainCount already, so don't release. You only release
// those items for which you increased retainCount (e.g. via new, copy,
// mutableCopy, or alloc or anything you manually retained).
//
// [filePath release];
[iv release];
}
// show the picture in scrollview;
[self.klpScrollView1 setContentSize:CGSizeMake(size.width * numImage, size.height)];
self.klpScrollView1.pagingEnabled = YES;
self.klpScrollView1.showsHorizontalScrollIndicator = NO;
self.klpScrollView1.backgroundColor = [UIColor grayColor];
因此,您的代码将被简化(并更正)为:
//Here is pictures Data;
self.klpArry = self.pictureData;
CGSize size = self.klpScrollView1.frame.size;
for (int i=0; i < [klpArr count]; i++) {
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake((size.width * i)+300, 20, 546, 546)];
NSString *filePath = [[NSBundle mainBundle] pathForResource:[klpArr objectAtIndex:i] ofType:@"jpg"];
UIImage *imageData = [[UIImage alloc] initWithData:[NSData dataWithContentsOfFile:filePath]];
[iv setImage:imageData];
iv.backgroundColor = [UIColor grayColor];
[self.klpScrollView1 addSubview:iv];
[imageData release];
[iv release];
}
// show the picture in scrollview;
[self.klpScrollView1 setContentSize:CGSizeMake(size.width * numImage, size.height)];
self.klpScrollView1.pagingEnabled = YES;
self.klpScrollView1.showsHorizontalScrollIndicator = NO;
self.klpScrollView1.backgroundColor = [UIColor grayColor];
或者您可以通过使用 autorelease 进一步简化您的代码:
//Here is pictures Data;
self.klpArry = self.pictureData;
CGSize size = self.klpScrollView1.frame.size;
for (int i=0; i < [klpArr count]; i++) {
UIImageView *iv = [[[UIImageView alloc] initWithFrame:CGRectMake((size.width * i)+300, 20, 546, 546)] autorelease];
NSString *filePath = [[NSBundle mainBundle] pathForResource:[klpArr objectAtIndex:i] ofType:@"jpg"];
UIImage *imageData = [[[UIImage alloc] initWithData:[NSData dataWithContentsOfFile:filePath]] autorelease];
[iv setImage:imageData];
iv.backgroundColor = [UIColor grayColor];
[self.klpScrollView1 addSubview:iv];
}
// show the picture in scrollview;
[self.klpScrollView1 setContentSize:CGSizeMake(size.width * numImage, size.height)];
self.klpScrollView1.pagingEnabled = YES;
self.klpScrollView1.showsHorizontalScrollIndicator = NO;
self.klpScrollView1.backgroundColor = [UIColor grayColor];
顺便说一下,声明(带有 autorelease ):
UIImage *imageData = [[[UIImage alloc] initWithData:[NSData dataWithContentsOfFile:filePath]] autorelease];
可以简化为:
UIImage *imageData = [UIImage imageWithContentsOfFile:filePath];
这给你一个 UIImage , +0 retainCount (即您不必 release 它)从您的文件。
所以,最后的几点观察:
您真的应该回顾和研究 Advanced Memory Management Programming Guide .如果您是内存管理的新手,这本书会是一本密集的读物,但掌握这些概念(尤其是在非 ARC 代码中)至关重要。
如果您还没有,我鼓励您通过静态分析器(“Product” - “Analyze” 或 shift+command+B)。如果分析器没有为您识别其中的许多(如果不是大多数)问题,我会感到惊讶。通过分析器运行代码时,警告应该为零。
如果您想将其提升到一个新的水平,您可能希望对内存管理更加保守。管理原则是一个系统设计,在任何给定时间只加载 UI 需要的图像,这不仅涉及 calvinBhai 关于延迟加载图像的极好建议(即,在你的 UI really 需要它们),而且一旦图像滚出屏幕就会主动释放图像。也许你不需要在你的应用程序中担心它,因为你一次只处理 20 张图像,但如果你的任何一个投资组合/画廊扩展到 100 或 1000 张图像,那么将所有这些都保留在任何给定时间的内存都只是一个坏主意。这是一个更高级的概念,因此也许您应该首先关注现有代码的基本内存管理问题,但从长远来看,您可能需要考虑延迟加载和主动释放图像。
关于iphone - UIImageView 和 UIScrollView 加载大量图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12362294/
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我是Rails的新手,所以请原谅简单的问题。我正在为一家公司创建一个网站。那家公司想在网站上展示它的客户。我想让客户自己管理这个。我正在为“客户”生成一个表格,我想要的三列是:公司名称、公司描述和Logo。对于名称,我使用的是name:string但不确定如何在脚本/生成脚手架终端命令中最好地创建描述列(因为我打算将其设置为文本区域)和图片。我怀疑描述(我想成为一个文本区域)应该仍然是描述:字符串,然后以实际形式进行调整。不确定如何处理图片字段。那么……说来话长:我在脚手架命令中输入什么来生成描述和图片列? 最佳答案 对于“文本”数
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
如何只加载map边界内的标记gmaps4rails?当然,在平移和/或缩放后加载新的。与此直接相关的是,如何获取map的当前边界和缩放级别? 最佳答案 我是这样做的,我只在用户完成平移或缩放后替换标记,如果您需要不同的行为,请使用不同的事件监听器:在你看来(index.html.erb):{"zoom"=>15,"auto_adjust"=>false,"detect_location"=>true,"center_on_user"=>true}},false,true)%>在View的底部添加:functiongmaps4rail
我正在尝试找出一种方法来显示来自不在RAILS_ROOT下(在RedHat或Ubuntu环境中)的已安装文件系统的图像。我不想使用符号链接(symboliclink),因为这个应用程序实际上是通过Tomcat部署的,而当我关闭Tomcat时,Tomcat会尝试跟随符号链接(symboliclink)并删除挂载中的所有图像。由于这些文件的数量和大小,将图像放在public/images下也不是一种选择。我查看了send_file,但它只会显示一张图片。我需要在一个格式良好的页面中显示6个请求的图像。由于膨胀,我宁愿不使用Base64编码,但我不知道如何将图像数据与呈现的页面一起传递下去。
我需要做这样的事情classUser'User',:foreign_key=>'abuser_id'belongs_to:gameendclassGame['JOINabuse_reportsONusers.id=abuse_reports.abuser_id','JOINgamesONgames.id=abuse_reports.game_id'],:group=>'users.id',:select=>'users.*,count(distinctgames.id)ASgame_count,count(abuse_reports.id)asabuse_report_count',:
我指的是pubrailscasttutorial并已正确执行所有步骤,但在运行最后一个命令时,即rackupprivate_pub.ru-sthin-Eproduction为了架设faye服务器,我收到以下错误:/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in`require':cannotloadsuchfile--thin(LoadError)from/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in`require'from/var/lib/gems/1.9.1/gems
我们在服务器端遇到libxml-rubygem的问题可能是因为它使用x86_64架构:$uname-aLinuxip-10-228-171-642.6.21.7-2.fc8xen-ec2-v1.0#1SMPTueSep110:25:30EDT2009x86_64GNU/Linuxrequire'libxml'LoadError:/usr/local/ruby-enterprise/lib/ruby/gems/1.8/gems/libxml-ruby-1.1.4/lib/libxml_ruby.so:invalidELFheader-/usr/local/ruby-enterprise/