如何将NSCache与多条信息一起用作“关键”?

时间:2013-06-25 17:10:46

标签: objective-c

我正在尝试理解NSCache的概念,有一件事让我感到震惊的是,NSCache实例并不保证将值返回给您之前存储的密钥。当您尝试添加密钥值对时,它甚至可能不存储密钥值对,如果它认为此时性能更重要的话。

对我来说,这意味着:

  1. 每个密钥必须“保留”足够的信息以在必要时生成值
  2. NSCache的每个查询(基本上只是一个键的形式)应该包含生成相应值所需的所有信息。
  3. 从以上两点可以看出,NSCache没有用于在密钥和值之间建立任何类型的关联 - 用户必须能够独立于缓存生成值,并且唯一的目的是使用NSCache不是要“查找”一些价值,而只是为了提高内存以获得一些性能提升
  4. 所以我的问题是存储图像的透明蒙版。最初我认为我只需要使用图像的名称作为键,但从我上面的推论看来,这似乎还不够 - 我还必须包括用于生成掩码的所有其他参数,例如:例如,透明度阈值。这也意味着每次我向缓存请求掩码时我都必须提供所有参数。而我能想到的唯一方法是使用NSInvocation之类的东西作为关键;但这似乎是一个相当笨重的解决方案。

2 个答案:

答案 0 :(得分:2)

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

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

对于密钥,您可以创建一个非常简单的类,它只包含一些属性(构成密钥的属性),isEqual:hash方法以及初始化程序为每个属性提供参数。

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

这个类对于你需要它的特殊情况来说是如此之小和制作,在你将要使用它的.m文件的顶部声明并实现它是有意义的。这种方式,你不会污染系统的其他部分。只需在.m文件的顶部为您的班级添加@interface@implementation部分。

答案 1 :(得分:0)

在考虑了这个之后我觉得我有一件事是错误的 - NSCache中的密钥不一定需要保存所有生成值的信息。 NSCache中的密钥可以起到与NSDictionary中相同的作用 - 一个用于查找值的唯一标识符。但唯一的区别是,如果之前添加的键值对被销毁,您总是需要为NSCache设置备份计划B.

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

<强>的NSDictionary

  1. 为每个键V生成每个值K并将这些对添加到词典
  2. 使用V
  3. 查找K

    <强> NSCache

    1. 使用V
    2. 查找K
    3. 如果V == nil,则生成值V并将该对添加到缓存
    4. 因此,几乎可以将任何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中。