面试题

作者: Jorunk | 来源:发表于2018-07-10 23:01 被阅读19次

    1.MVC和MVP的区别以及使用的优缺点是什么?

    • MVP:面向协议的编程
      • mode发起网络请求,像服务器请求数据
      • mode把数据给presenter,presenter要写一个接口\协议,这个接口是外面谁想使用我的数据,就遵守我的协议,调用这个接口
      • controller里面没有网络请求
      • view和mode之间可以解耦
      • 网络请求写在mode里面
      • 逻辑代码写在presenter里面

    2.MVC经典的架构中说说有哪些常用的设计模式

    • 代理模式
    • 观察者模式
    • 命令模式(target-action模式)
    • 中介者模式
    • 策略模式

    3.怎么解决iOS打包成功之后,运行在iPhone上会上会闪退,黑屏的问题?

    4.说一说OC中的字典的实现的原理

    • 哈希表
      • 本质是一个数组

    5.iOS中的消息发送机制和消息转发机制的区别?

    • 消息发送机制:使用了运行时,通过selector快速去查找IMP的一个过程
    • 消息转发机制:IMP找不到的时候,通过一些方法做转发处理

    6.组件间的通讯,是通过什么方式来做的,请详细的解释一下

    • 组件间的通讯是采用路由的方式

    7.SDWebImage是怎么来清理缓存的?

    - (id)init
    {
        self = [super init];
        if (self) {
            //上面使用是继承自NSCache,自动清除缓存
            //由父类的removeAllObjects来做
            //发出通知
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
        }
        return self;
    }
    
    
    //清理磁盘
    - (void)cleanDisk {
        [self cleanDiskWithCompletionBlock:nil];
    }
    //清除缓存,异步操作:1.清除过期的缓存文件;2.缓存超过设定阈值时,按时间顺序删除缓存中的图片,直到缓存剩余空间达到阈值的一半
    - (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock {
        dispatch_async(self.ioQueue, ^{
            //1.找到磁盘缓存目录
            NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
            /*
             NSURLIsDirectoryKey,目录key
             NSURLContentModificationDateKey,url指向的内容,最后修改时间的key
             NSURLTotalFileAllocatedSizeKey文件总大小的key
             
             resourceKeys包含要了解的属性:允许判断遍历到URL所指向对象是否为目录,允许判断遍历返回的URL所指项目的最后修改时间、URL目录中所分配空间大小
             */
            NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey];
    
            //3.enumerator(链表的数据结构存在)迭代器设计模式
            //使用目录枚举器获取缓存文件
            //使用NSDirectoryEnumerator遍历所有缓存文件,获取文件属性,如我们需要的文件大小信息,是不会有性能问题的。NSDirectoryEnumerator获取文件属性是通过查看文件的inode数据,并不需要想象中的fileopen和fileclose
            //创建文件目录的枚举器
            /*
            **不要下载到目录
            NSDirectoryEnumerationSkipsSubdirectoryDescendants = 1UL << 0,
             
            NSDirectoryEnumerationSkipsPackageDescendants will cause the NSDirectoryEnumerator to not descend into packages.
            **不要下载包
            NSDirectoryEnumerationSkipsPackageDescendants      = 1UL << 1,
            
            NSDirectoryEnumerationSkipsHiddenFiles causes the NSDirectoryEnumerator to not enumerate hidden files.
            **不遍历隐藏文件
            NSDirectoryEnumerationSkipsHiddenFiles             = 1UL << 2
            
            */
            // This enumerator prefetches useful properties for our cache files.
            NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL
                                                       includingPropertiesForKeys:resourceKeys
                                                                          options:NSDirectoryEnumerationSkipsHiddenFiles
                                                                     errorHandler:NULL];
            //4.从现在开始计算,减去最大时间
            //计算过期时间,默认一周以前的缓存文件为过期
            NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge];
            
            //5.定义一个字典
            //当前保存下来文件fileURL
            NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary];
            
            //6.定义了当前缓存的大小
            NSUInteger currentCacheSize = 0;
    
            
            
            //7.创建一个可变数组/将要删除的文件fileURL数组
            // Enumerate all of the files in the cache directory.  This loop has two purposes:
            //
            //  1. Removing files that are older than the expiration date.
            //  2. Storing file attributes for the size-based cleanup pass.
            NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init];
            for (NSURL *fileURL in fileEnumerator) {
                //9.获取制定key的信息,以字典的方式返回
                NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL];
    
                //10.判断这个目录,有就直接跳过
                // Skip directories.
                if ([resourceValues[NSURLIsDirectoryKey] boolValue]) {
                    continue;
                }
    
                //11.拿到文件的修改日期
                // Remove files that are older than the expiration date;
                NSDate *modificationDate = resourceValues[NSURLContentModificationDateKey];
                
                //12.记录超过过期文件的fileURL
                if ([[modificationDate laterDate:expirationDate] isEqualToDate:expirationDate]) {
                    [urlsToDelete addObject:fileURL];
                    continue;
                }
    
                //14.保存保留下来的文件的引用并计算文件总的大小
                // Store a reference to this file and account for its total size.
                NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
                currentCacheSize += [totalAllocatedSize unsignedIntegerValue];
                [cacheFiles setObject:resourceValues forKey:fileURL];
            }
            
            //15.删除缓存中的过期文件
            for (NSURL *fileURL in urlsToDelete) {
                [_fileManager removeItemAtURL:fileURL error:nil];
            }
    
            //当设置的maxCacheSize > 0 且 当前缓存中的文件所占内存大于设置的最大缓存时,按顺序删除文件,知道缓存剩余空间达到阈值的一半
            // If our remaining disk cache exceeds a configured maximum size, perform a second
            // size-based cleanup pass.  We delete the oldest files first.
            if (self.maxCacheSize > 0 && currentCacheSize > self.maxCacheSize) {
                
                //16.清除缓存目标是最大缓存的一半
                // Target half of our maximum cache size for this cleanup pass.
                const NSUInteger desiredCacheSize = self.maxCacheSize / 2;
    
                
                //缓存文件排序,最老的文件先清除
                //NSSortConcurrent 并行的方式
                // Sort the remaining cache files by their last modification time (oldest first).
                NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent
                                                                usingComparator:^NSComparisonResult(id obj1, id obj2) {
                                                                    return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]];
                                                                }];
    
                
                /*
                 两种方式
                 一、根据时间顺序,七天过期,删除掉
                 二、把之前没删除的按时间先后的顺序存储起来。根据自定义的最大缓存,删除一半
                 
                 */
                //遍历删除文件,直到低于缓存大小
                // Delete files until we fall below our desired cache size.
                for (NSURL *fileURL in sortedFiles) {
                    if ([_fileManager removeItemAtURL:fileURL error:nil]) {
                        NSDictionary *resourceValues = cacheFiles[fileURL];
                        NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
                        currentCacheSize -= [totalAllocatedSize unsignedIntegerValue];
    
                        if (currentCacheSize < desiredCacheSize) {
                            break;
                        }
                    }
                }
            }
            if (completionBlock) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    completionBlock();
                });
            }
        });
    }
    

    8.SDWebImage是怎么处理处理接受的内存的警告的?

    #if TARGET_OS_IPHONE
            
            //内存警告时,清理缓存
            // Subscribe to app events
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(clearMemory)
                                                         name:UIApplicationDidReceiveMemoryWarningNotification
                                                       object:nil];
    
            //应用在前台终止时,清理换UN
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(cleanDisk)
                                                         name:UIApplicationWillTerminateNotification
                                                       object:nil];
    
            //应用进入后台时,清理磁盘
            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(backgroundCleanDisk)
                                                         name:UIApplicationDidEnterBackgroundNotification
                                                       object:nil];
    #endif
    

    9.SDWebImage中怎么计算图片的成本大小?

    #pragram mark --
    //计算图片所占大小
    FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
        
        //计算图片所消耗的内存
        //注意乘以屏幕的比例因子
        return image.size.height * image.size.width * image.scale * image.scale;
    }
    
    #pragma mark -- 计算缓存大小、缓存中的图片数
    //同步操作:获取缓存中的所有文件的大小
    - (NSUInteger)getSize {
        __block NSUInteger size = 0;
        //需要同步操作:等待队列self.ioQueue中的任务执行完后(有可能队列中的任务正在添加或者删除图片操作时),再进行获取文件大小的计算
        dispatch_sync(self.ioQueue, ^{
            NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
            for (NSString *fileName in fileEnumerator) {
                NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];
                NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
                size += [attrs fileSize];
            }
        });
        return size;
    }
    
    //同步操作:获取磁盘缓存中图片数
    - (NSUInteger)getDiskCount {
        __block NSUInteger count = 0;
        dispatch_sync(self.ioQueue, ^{
            NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
            count = [[fileEnumerator allObjects] count];
        });
        return count;
    }
    

    10.SDWebImage中clear和clean有什么样的区别?

    • clear:全部删除
    • clean:1.周期2.大小来删除

    相关文章

      网友评论

          本文标题:面试题

          本文链接:https://www.haomeiwen.com/subject/rjqcpftx.html