0

我试图理解 NSCache 的概念,让我印象深刻的一件事是 NSCache 实例并不能保证将值返回给您之前存储的键。如果它认为此时性能更重要,它甚至可能在您尝试添加它时不存储键值对。

对我来说,这意味着:

  1. 每个键必须“保存”足够的信息以在必要时生成值
  2. NSCache 的每个查询,本质上只是一个键的形式,因此应该包含生成相应值所需的所有信息。
  3. 从以上两点可以说,NSCache 的目的不是在键和值之间建立任何类型的关联——用户必须能够独立于缓存生成值,而使用 NSCache 的唯一目的不是“查找”一些值,而只是用内存换取一些性能提升

所以我的问题是关于存储图像的透明蒙版。最初我以为我只需要使用图像的名称作为键,但从我上面的推论看来这还不够——我还必须包括用于生成遮罩的所有其他参数,例如透明度阈值。这也意味着每次我向缓存请求掩码时,我都必须提供所有参数。我能想到的唯一方法是使用类似的东西NSInvocation作为键;但这似乎是一个相当笨拙的解决方案。

4

2 回答 2

2

缓存的本质是易失的,因此缓存应该只用于加速对也可以通过其他方式获取的信息的访问。

您创建包含所有这些信息的密钥的想法应该可行 - 只需记住将所有密钥存储在缓存以外的其他地方。

至于键,您可以创建一个非常简单的类,它只有几个属性(构成键的属性)、一个isEqual:hash方法,也许还有一个初始化器,它为每个属性获取参数。

这需要极少的代码,因为属性的访问器和 iVar 是自动生成的,所以您真正需要编写的只是isEqual:方法(和hash)。

这个类是如此之小,并且是为您需要它的特定情况而定制的,因此在您将要使用它的 .m 文件的顶部声明和实现它是有意义的。这样,您不需要污染系统的其余部分。只需在 .m 文件的顶部为您的课程添加@interface和部分。@implementation

于 2013-06-25T17:18:31.877 回答
0

经过更多的思考,我认为我有一个问题 - NSCache 中的键不一定需要保存所有信息以生成值。NSCache 中的键可以起到与 NSDictionary 中相同的作用——查找值的唯一标识符。但是,唯一的区别是,您总是需要为 NSCache 制定备份计划 B,以防之前添加的键值对被破坏。

简单来说,对两个不同类的操作如下所示:

NS词典

  1. V为每个键生成每个值K并将对添加到字典中
  2. 查找V使用K

NSCache

  1. 查找V使用K
  2. 如果V == nil,生成值V并将该对添加到缓存中

因此,几乎可以将任何 NSDictionary 转换为 NSCache,只是在转换后您无法传递 NSCache - 您必须始终知道如何生成值,因此 NSCache 实例很可能是私有属性专门用于某一类。

对于我的问题,我已经决定使用这样的方法(self据说是指向 NSCache 的子类,但我还没有测试过)

- (Mask *) maskForImageName:(NSString *)name maskGenerator:(Mask *(^)(NSString *))generator {
    Mask *mask = [self objectForKey:name];
    if (!mask) {
        mask = generator(name);
        [self setObject:mask forKey:name];
    }
    return mask;
}

如果 Objective-c 是一种函数式、惰性风格的语言,它会进一步简化,在这种情况下,我什至不需要将生成器包装在一个块中;但我现在对这个解决方案很满意。事实上,我觉得这种模式几乎总是与 NSCache 一起使用,所以我只是将它作为一个类别添加到 NSCache 中。

于 2013-06-25T18:39:23.690 回答