最近在做我们公司自己的项目时,遇到了一个难题,就是随着用户使用我们公司的app时间越久,便导致app沙盒文件越来越多,严重时我查看我们公司的app使用内存量达到了7.3G
,查看方式,打开你的苹果手机,(设置-通用-储存空间及iCloud用量-管理储存空间
);怎么样不查不知道一查是不是吓一跳?
细说下我们公司app占用内存量大的原因,我们公司的app属于类社交和OA类,其中有类似微信的朋友圈和聊天,及收藏功能,所以当用户发图片很多时,图片都存入自己的沙盒中,当用户在聊天页面点击图片收藏,图片会复制一份并生成新的图片再次上传服务器,同时新生成的图片也会copy到我们已经规定好的沙盒中的收藏文件夹(之所以给每个模块都在沙盒目录中规定一个文件夹,为了便于清理,注:每个聊天会话的图片都存在它特定的文件夹下,删除某一条会话时,会话下的图片也能得到及时清除)下。同理,在朋友圈中的图片也可以收藏。所以当图片少的时候暂时没有发现问题,而且似乎感觉还很好,因为每次文件清理直接拿到每一个模块的路径文件夹清理就可以。然而,随着时间的推移,用户选择的文件的越来越多,便产生一开始描述的问题。附路径地址:/Users/liangju/Library/Developer/CoreSimulator/Devices/6184D61E-A799-4127-881E-F71E3D9CD61B/data/Containers/Data/Application/F83F1BC6-4809-40B9-80EC-D1EC7FEF2FBA/Documents/my_app/1BdWrWKyJ8MUpM7ofJsa4g/file/CC_OPEN_MESSAGE/
g_2BwfR0iZJedUvP6ispaOAp/168D8A9C8830461AAC6C6711C9136115.jpg
其中地址中my_app 为app名字,1BdWrWKyJ8MUpM7ofJsa4g为登录人id,CC_OPEN_MESSAGE为服务id,也就是下文中的SERV_ID,u_2aRr2i4UF5dkXExQMVTly1I为绘画id,其中我们公司规定以u开头是单人绘画,g开头为群组绘画,同时此项也就是下文中的DATA_ID,再往下就是image对象名字了/Users/liangju/Library/Developer/CoreSimulator/Devices/6184D61E-A799-4127-881E-F71E3D9CD61B/data/Containers/Data/Application/F83F1BC6-4809-40B9-80EC-D1EC7FEF2FBA/Documents/my_app/1BdWrWKyJ8MUpM7ofJsa4g/file/CC_OPEN_MESSAGE/
u_2aRr2i4UF5dkXExQMVTly1I/317C7D7B10D847B09F4CE827BC8EB78F.jpg
所以便想能不能把这些文件统一管理起来,比如聊天中的图片再收藏时(前提此图片已经上传服务器成功,上传失败的情况我们稍后讨论),能不能不在复制产生新的图片上传,收藏模块的图片直接去聊天的那张图片路径下,把这张图片读出显示。
实现篇:统一封住文件最终下载所调的接口。每个文件下载时都给它固定了一个下载路径。当它下载成功后,把文件对应的服务器的文件id,保存到数据表中。结合每个公司的不同情况合理设置缓存模型,我们公司的设置如下:
1 | // 文件在服务端的id |
其次在每次下载图片的时候,1,先从sd内存缓存里读出图片,若读出直接block image对象;2,若不存在image,则需要先根据SERVER_FILEID查一下本地是否已经存在那条数据,如果存在,根据路径读出图片,再根据SERV_ID、DATA_ID、SERVER_FILEID再次查找本地表是否存在这条数据,如果不存在,则新建一条数据;当根据SERVER_FILEID在本地表中查找不到时,继续往下走,调用图片下载方法(我们采用的图片下载三方为sd),以下为相关代码:
1 | - (void)rh_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock rhImgParam:(RHImageParam *)rhImgParam { |
1 | /** |
接下来我们来处理图片上传的情况:在上传图片接口;无论成功,失败都要将其结果保存数据库,只是失败时不存在SERVER_FILEID;其次在处理上传成功的图片,在其保存前先根据SERV_ID,DATA_ID,PATH查寻缓存表,看这条数据是否已经存在,若存在,只需更新表,把SERVER_FILEID更新至表中,若不存在,则生成一条新的数据保存至表中。
1 | /** |
1 | /** |
删除逻辑:删除时首先根据SERVER_FILEID查表中数据,如果大于1,说明此文件被多个地方引用,不删除文件,仅根据SERV_ID,DATA_ID,SERVER_FILEID,删出表中这条数据;若根据SERVER_FILEID查表中数据等于1,删除文件,同时根据SERV_ID,DATA_ID,SERVER_FILEID,删出表中这条数据。