当前位置:首页 > 问答 > 正文

iOS里图片怎么存数据库啊,数据直接写进去是不是挺麻烦的?

(用户询问iOS里图片怎么存数据库,数据直接写进去是不是挺麻烦的?)

直接回答:是的,直接把图片数据存进数据库,比如SQLite,确实挺麻烦的,而且通常不被推荐,原因很简单,图片文件一般都比较大,而数据库在处理大量二进制大对象(也就是我们常说的BLOB数据)时,性能会成为一个大问题,想象一下,你把很多张高清照片塞进数据库里,这个数据库文件会迅速膨胀,每次你读取或者显示一张图片,数据库都需要去这个巨大的文件里把对应的二进制数据找出来、加载到内存里,这会非常慢,消耗很多内存,还可能影响应用其他操作的流畅度,数据库的备份和迁移也会因为文件太大而变得困难重重。

(那应该怎么做呢?)

更常见、也更高效的做法是采用“文件系统存储 + 数据库索引”的方式,简单说,就是把图片本身以文件的形式保存在手机的某个目录下(比如应用的Documents或Caches目录),然后只在数据库里保存这个图片文件的路径(一个字符串),当你需要显示某张图片时,你先从数据库里读出它的文件路径,再根据这个路径去文件系统里加载图片。

(具体怎么操作?)

你得把图片保存为文件,在iOS开发中,你通常会用到UIImage对象,你可以把这个UIImage转换成Data数据,这可以通过UIImageJPEGRepresentationUIImagePNGRepresentation函数来实现,前者会进行有损压缩,文件小一些;后者是无损压缩,文件大一些但保真度高,你需要为这个图片文件想一个唯一的名字,比如用时间戳或者生成一个UUID(通用唯一识别码),这样可以避免重名覆盖,你构造一个文件在应用沙盒内的完整保存路径,最后调用Datawrite(to: options:)方法把数据写入到这个路径。

(文件存好了,数据库里存什么?)

文件保存成功后,你会得到一个本地文件路径,比如file:///var/mobile/Containers/Data/Application/你应用的唯一标识/Documents/ABC123DEF.jpg,你不需要把整个图片数据存进数据库了,只需要在数据库对应的表里,用一个文本类型的字段(比如叫imagePath)来记录下这个完整的路径字符串,你很可能还会记录图片的其他信息,比如标题、创建时间、所属相册等,这些都一起存到数据库的同一行记录里。

(要用的时候怎么取?)

当你的应用需要显示这张图片时,流程是这样的:从数据库查询那条记录,取出imagePath字段的值,使用这个路径字符串创建一个URL或直接作为路径,通过UIImage(contentsOfFile:)初始化方法来加载图片,如果路径正确,你就能得到UIImage对象,然后就可以把它显示在UIImageView上了。

(有没有更方便的框架?)

如果你觉得从零开始处理这些文件读写和数据库操作还是有些繁琐,可以考虑使用一些第三方封装好的库,它们让这个过程变得更简单,比如很受欢迎的FMDB,它是一个对SQLite的Objective-C封装,让你用起来更顺手,还有Realm,它是一个跨平台的移动数据库,本身对二进制数据的支持就比较好,而且API更现代化,Core Data作为苹果官方提供的对象图管理和持久化框架,它有一个Binary Data的属性类型,并且你可以勾选一个叫“Allows External Storage”的选项,当你勾选了这个选项后,Core Data会智能地帮你判断:如果数据量小,它可能直接存在数据库里;如果数据量大(比如图片),它会自动帮你把数据存储为外部文件,并在数据库里只保存一个引用,这相当于帮你自动化了“文件系统+数据库索引”的过程,减少了手动操作的麻烦。

在iOS应用里存储图片,直接往数据库里塞二进制数据是下策,因为它有性能瓶颈,上策是采用“存路径”的方式:图片文件保存在沙盒,路径字符串保存在数据库,这样做的好处是数据库小而快,图片的加载和管理也更符合文件系统的设计初衷,如果追求开发效率,可以借助Core Data(开启外部存储选项)或Realm这类高级工具来简化工作。

iOS里图片怎么存数据库啊,数据直接写进去是不是挺麻烦的?