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
相關文章
相關標籤/搜索