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.大小来删除
网友评论