面试题

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

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

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

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

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

  • 证书错误
  • 设备没有在开发者账号
    • iOS证书自助管理实现思路(https://blog.csdn.net/seafishyls/article/details/50868661)

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.大小来删除

你可能感兴趣的:(面试题)