MKTilelOverlay 中的 NSCache

Posted

技术标签:

【中文标题】MKTilelOverlay 中的 NSCache【英文标题】:NSCache in a MKTilelOverlay 【发布时间】:2015-01-16 21:24:08 【问题描述】:

我正在尝试将NSCache 添加到我的子类MKTileOverlay 类中:

@interface WMSTileOverlay ()

@property NSCache *cache;

@end

@implementation WMSTileOverlay

-(instancetype)initWithURLTemplate:(NSString *)URLTemplate 
    self = [super initWithURLTemplate:URLTemplate];

    if (self) 
        DLog(@"setting cache");
        self.cache = [[NSCache alloc] init];
        DLog(@"original self.cache: %@", self.cache);

    

    return self;

-(void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *, NSError *))result 
if (!result) 
    return;


NSData *cachedData = [self.cache objectForKey:[self URLForTilePath:path]];
if (cachedData) 
    DLog(@"Cached tile found!!!!!!!");
    result(cachedData, nil);
 else 

    NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) 
        if (connectionError) 
            result (nil, connectionError);
        
        else 
            DLog(@"adding data to cache for tile %@", [self URLForTilePath:path]);
            DLog(@"cache: %@", self.cache);
            [self.cache setObject:data forKey:[self URLForTilePath:path]];

            if ([self.cache objectForKey:[self URLForTilePath:path]]) 
                DLog(@"found the data for url path");
            
            result (data, nil);
        
    ];

但我从来没有看到从缓存中获取磁贴(我从来没有看到日志消息“找到缓存磁贴!!!!!!”)。

我可能做错了什么?

编辑:我在日志信息中添加了

我添加了一堆日志记录。我检查是否创建了缓存,以及它是否与我在查找图块时引用的缓存相同。我还检查了数据是否已添加到缓存中,并在添加后立即找到:

DEBUG | -[WMSTileOverlay initWithMapContext:andLayer:] | original self.cache: <NSCache: 0x1bf59e10>
DEBUG | __40-[WMSTileOverlay loadTileAtPath:result:]_block_invoke | adding data to cache for tile service=wms&version=1.1.1&request=GetMap&SRS=EPSG:4326&layers=displayimg&mode=tiled&tile=30295+46150+17&format=image/png&transparent=true
DEBUG | __40-[WMSTileOverlay loadTileAtPath:result:]_block_invoke | cache: <NSCache: 0x1bf59e10>
DEBUG | __40-[WMSTileOverlay loadTileAtPath:result:]_block_invoke | found the data for url path

【问题讨论】:

你确定connectionErrornil 吗?也许datanil。您是否过于频繁地致电loadTileAtPath,并且在对同一资产的下一个请求通过之前没有让sendAsynchronousRequest 回复? 数据不为零,我看到地图上的瓦片加载了。 您确定调用了初始化程序吗?是否有可能永远不会创建缓存,因此永远不会发生命中?您可以尝试通过在 setObject:... call 周围添加日志行来确保正确更改缓存 是的,我很肯定正在调用初始化程序。 我还添加了一个IF语句来查看数据是否真的被添加到缓存中并且确实是。我添加后立即找到它。我想知道MKTileOverlay 是否有自己的缓存系统。当我缩小并重新缩小时,它并不总是重新获取磁贴,但由于磁贴的图像,我无法 100% 判断它是正确的缩放级别磁贴还是较低缩放级别的磁贴(缩放数字越小,您就越缩小)放大。 【参考方案1】:

这是因为一旦加载了特定路径的图块,MapKit 不会在同一会话中再次为该路径调用 loadTileAtPath,我认为 MapKit 已经以某种方式在内部缓存了加载的图块。

【讨论】:

我认为你是对的。我注意到如果应用程序长时间处于空闲状态,如果我再次移动地图,它将从我的缓存中加载图块。我假设在 X 时间之后,MapKit 会清除其缓存,然后在我的缓存中找到该图块。

以上是关于MKTilelOverlay 中的 NSCache的主要内容,如果未能解决你的问题,请参考以下文章

用于存储 UIImage ios 的 NSCache 初始化

NSCache

NSCache

如何使用 NSCache

NSCache的使用

说说NSCache优于NSDictionary的几点