• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

MKTileOverlay 和 PINCache 库的 iOS/MapKit 缓存管理问题

[复制链接]
菜鸟教程小白 发表于 2022-12-11 18:12:31 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在使用 MapKit 通过在 mapView 上添加 MKTileOverlay 来创建卫星和雷达动画。

使用 UISlider 和 PlayButton,我可以通过播放 MKOverlayRenderer 的 alpha(根据 slider 的位置将它们设置为 0 或 0.75)来创建动画,例如 GIF。

动画非常流畅,我所有的卫星和雷达图 block 都在 mapView 上正确加载。

我在缓存管理方面遇到了一个问题。

我意识到 MapKit 没有为我的 tileOverlay 使用缓存,这就是为什么我使用库 PINCache 来保存我的图 block ,这样它就不会在我每次播放动画时请求和下载图像。

我的实现:

我重写了方法 URLForTilePath 以构建我的 URL 来获取我的平铺图像。

- (NSURL *)URLForTilePathMKTileOverlayPath)path{

double latMin, latMax, longMin, longMax;
path.contentScaleFactor = 1.0;

NSMutableArray *result = [[NSMutableArray alloc] init];
result = getBBoxForCoordinates((int)path.x, (int)path.y, (int)path.z);

longMin = [[result objectAtIndex:0] doubleValue];
latMin = [[result objectAtIndex:1] doubleValue];
longMax = [[result objectAtIndex:2] doubleValue];
latMax = [[result objectAtIndex:3] doubleValue];

NSString *finalURL = self.url;
finalURL = [finalURL stringByReplacingOccurrencesOfString"DATE"
                                     withString:_date];

NSString *bbox = [NSString stringWithFormat"bbox=%f,%f,%f,%f", longMin, latMin, longMax, latMax];
finalURL = [finalURL stringByReplacingOccurrencesOfString"BBOX"
                                     withString:bbox];

return [NSURL URLWithString:finalURL];
}

调用 URLForTilePath 的关键方法是我对 loadTileAtPath 的实现:

    - (void)loadTileAtPathMKTileOverlayPath)path
                resultvoid (^)(NSData *data, NSError *error))result
{
    if (!result)
    {
        return;
    }

    NSString *str = self.isRadar == true ? [NSString stringWithFormat"Radar%@", self.date] : [NSString stringWithFormat"Satellite%@", self.date];
    NSData *cachedData = [[PINCache sharedCache] objectForKey:str];
    if (cachedData)
    {
        result(cachedData, nil);
    }
    else
    {
        NSURLRequest *request = [NSURLRequest requestWithURL:[self URLForTilePath:path]];
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            NSString *str = self.isRadar == true ? [NSString stringWithFormat"Radar%@", self.date] : [NSString stringWithFormat"Satellite%@", self.date];
            [[PINCache sharedCache] setObject:data forKey:str block:nil];
            result(data, connectionError);
        }];
    }
}

基本上我想要实现的是:

  • 检查我是否有缓存数据,如果有则获取对象。
  • 如果没有,我会发出请求以下载具有 URLForTilePath 给出的 URL 的磁贴。
  • 然后我将对象设置为缓存。
  • 字符串str是我的缓存管理Key
  • 为了对图 block 进行排序和区分,我有 2 个重要的值、类型(雷达或卫星、不同的图像、不同的 URL)和日期。

我可以看到缓存管理正在运行,叠加层的渲染速度更快,但我遇到的主要问题是它没有在相应的坐标处加载和构建图 block 。

我的 mapView 就像一个错误构建的世界的拼图。

通过我的一段代码,你能看出我做错了什么吗?



Best Answer-推荐答案


我找不到 mapKit 出现内存/缓存管理问题的原因。

我决定尝试使用 GoogleMap,实现它只用了不到 2 个小时,结果令人惊叹。

我想通过使用 Apple 解决方案来尊重 Apple 社区,但 Google map 为我提供了更多的表现。

关于MKTileOverlay 和 PINCache 库的 iOS/MapKit 缓存管理问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40907584/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap