iOS 获取内存信息与NSCache用法说明

一.获取内存使用状况数组

获取iOS App运行时内存,能够经过以下模块xcode

#import<sys/sysctl.h> 
#import<mach/mach.h>

获取cpu核心数缓存

unsigned int countOfCores()  
{  
    unsigned int ncpu;  
    size_t len = sizeof(ncpu);  
    sysctlbyname("hw.ncpu", &ncpu, &len, NULL, 0);  
      
    return ncpu;  
}

获取方式以下,获取内存能够用空间安全

//获取当前设备可用内存,单位MB
 + (double)availableMemory{
      vm_statistics_data_t vmStats;
      mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
      kern_return_t kernReturn = host_statistics(mach_host_self(),
                                           HOST_VM_INFO,
                                           (host_info_t)&vmStats,
                                           &infoCount);

    if (kernReturn != KERN_SUCCESS) {
    return NSNotFound;
    }
    return ((vm_page_size * vmStats.free_count)/1024.0)/1024.0;
}

获取当前内存占用状况多线程

//获取当前任务所占用内存,单位MB
+ (double)usedMemory{
    task_basic_info_data_t taskInfo;
    mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
    kern_return_t kernReturn = task_info(mach_task_self(),
                                     TASK_BASIC_INFO,
                                     (task_info_t)&taskInfo,
                                     &infoCount);

      if (kernReturn != KERN_SUCCESS) {
      return NSNotFound;
      }
      return taskInfo.resident_size/1024.0/1024.0;
}

获取app运行总内存app

double memoryTotalSize = [SystemCpu availableMemory] + [SystemCpu usedMemory]

 

2、NSCache使用ide

1.NSCache的用法和NSMutableDictionary的区别atom

  • NSCache 是能够自动释放内存一部分的(当内存吃紧时,自动删除一些项目,并非释放NSCache实例)。
  • NSCache 是线程安全的,咱们能够在不一样的线程中添加,删除和查询缓存中的对象。NSMutable默认都是不安全的。注意,多线程状况下,NSCache仍然可能不够安全,须要加锁。
  • NSCache  一个缓存对象不会拷贝key对象,而是直接引用key。

2.NSCache缓存图片url

NSCache具有线程安全、自动释放Cache Item对象的特性,能够用来实现二级缓存。线程

#import "ViewController.h"
#import "WJCellItem.h"
@interface ViewController ()
//定义数组来存储从plist中加载的数据
@property (strong,nonatomic)NSArray *dataArr;
//在内存中存储图片的容器
@property (strong,nonatomic)NSCache *images;
//存储操做的字典
@property (strong,nonatomic)NSMutableDictionary *operations;
//队列
@property (strong,nonatomic)NSOperationQueue *queue;
@end

@implementation ViewController
//懒加载建立存储数据的数组
-(NSArray *)dataArr{
    if (_dataArr==nil) {
        NSString *path=[[NSBundle mainBundle]pathForResource:@"apps.plist" ofType:nil];
        NSArray *array=[NSArray arrayWithContentsOfFile:path];
        NSMutableArray *arrM=[NSMutableArray array];
        for (NSDictionary *dict in array) {
            //把从数组中取出来的字典包装成模型
            WJCellItem *item=[WJCellItem cellItemWithDict:dict];
            [arrM addObject:item];
        }
        _dataArr=arrM;
    }
    return _dataArr;
}
//懒加载建立字典
-(NSMutableDictionary *)operations{
    if (_operations==nil) {
        _operations=[NSMutableDictionary dictionary];
    }
    return _operations;
}
//懒加载建立队列
-(NSOperationQueue *)queue{
    if (_queue==nil) {
        _queue=[[NSOperationQueue alloc]init];
    }
    return _queue;
}
//懒加载建立NSCache
-(NSCache *)images{
    if (_images==nil) {
        _images=[[NSCache alloc]init];
        //最多缓存100张图片
        _images.countLimit=100;
    }
    return _images;
}

//整个tableView只有一组
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 1;
}
//每一组有多少行
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.dataArr.count;
}
//每一行cell的内容
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    //设置cell的标示
    static NSString *ID=@"cell";
    //tableViwe的重用机制,先从缓冲池里找有没有对应标示的cell
    UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
    //若是在缓存池里找不到再来建立
    if (cell==nil) {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];

    }
    //取出模型,给cell设置数据
    WJCellItem *item=self.dataArr[indexPath.row];
    cell.textLabel.text=item.name;
    cell.detailTextLabel.text=item.download;
    //因为plist文件中给的是图片的url,因此须要咱们去下载
    //先去内存缓存中去找,若是内存缓存中有就直接取出来设置
    UIImage *image=[self.images objectForKey:item.icon];
    if (image) {
        cell.imageView.image=image;
        //若是内存缓存中没有就去沙盒(磁盘)里找,若是沙盒(磁盘)中有,就从沙盒(磁盘)中取出来设置,而且把图片保存到内存中
    }else{
        //获取沙盒路径
        NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        //获取图片路径的最后一个节点
        NSString *imagePath=[item.icon lastPathComponent];
        //拼接路径获取图片的全路径
        NSString *fullPath=[caches stringByAppendingPathComponent:imagePath];
        //从磁盘中试着取数据
        NSData *data=[NSData dataWithContentsOfFile:fullPath];
        if (data) {
            UIImage *image=[UIImage imageWithData:data];
            cell.imageView.image=image;
            //若是磁盘中也没有找到图片数据,咱们就先去操做字典中查找有没有这个图片的下载操做,若是有就等待下载完毕,若是没有就须要咱们手动下载
        }else{

            //在图片下载完成以前设置一张占位图片,以防止cell重用引起的图片错乱问题
            cell.imageView.image=[UIImage imageNamed:@"xcode"];
            //试着去存储操做的字典里找当前的下载操做
            NSBlockOperation *download=[self.operations objectForKey:item.icon];
            //若是在字典中没有找到该操做,就须要咱们手动下载了,因为下载图片是耗时操做,所以须要开启子线程下载
            if (download==nil) {
                //封装操做
                NSBlockOperation *download=[NSBlockOperation blockOperationWithBlock:^{
                    //获取图片的url
                    NSURL *url=[NSURL URLWithString:item.icon];
                    //根据图片的url将图片的二进制数据下载到本地
                    NSData *data=[NSData dataWithContentsOfURL:url];
                    //根据二进制数据生成一张图片
                    UIImage *image=[UIImage imageWithData:data];
                    //若是没有获得图片,直接返回,防止在设置图片的时候程序崩溃
                    if (image==nil) {
                        return ;
                    }
                    //将图片保存一份到内存中
                    [self.images setObject:image forKey:item.icon];
                    //将图片的二进制数据保存一份到磁盘中
                    [data writeToFile:fullPath atomically:YES];
                    //在主队列中设置图片
                    [[NSOperationQueue mainQueue]addOperationWithBlock:^{
                        //刷新表格
                        [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                    }];

                }];
                //将操做添加到队列中
                [self.queue addOperation:download];
                //将下载操做添加到缓存中一份,防止重复建立同一个操做
                [self.operations setObject:download forKey:item.icon];
            }else{
                //当在存储操做的字典里找到了当前的操做就会来到这个方法
                //在这里面不须要作任何操做,只须要等着图片加载完毕后显示便可
            }

        }

    }
    //返回当前的cell
    return cell;
}
//发生内存警告时的处理
-(void)didReceiveMemoryWarning{
    //清除图片缓存
    [self.images removeAllObjects];
    //取消全部的任务
    [self.queue cancelAllOperations];
}
@end

模型WJCellItem以下:

#import <Foundation/Foundation.h>

@interface WJCellItem : NSObject
@property (nonatomic,copy)NSString *name;
@property (nonatomic,copy)NSString *icon;
@property (nonatomic,copy)NSString *download;

+(instancetype)cellItemWithDict:(NSDictionary*)dict;
@end

#import "WJCellItem.h"

@implementation WJCellItem
+(instancetype)cellItemWithDict:(NSDictionary *)dict{
    WJCellItem *item=[[self alloc]init];
    [item setValuesForKeysWithDictionary:dict];
    return item;
}
@end
相关文章
相关标签/搜索