Objective c 如何将NSCache与多条信息一起用作';键';?

Objective c 如何将NSCache与多条信息一起用作';键';?,objective-c,Objective C,我正在试图理解NSCache的概念,有一件事让我印象深刻,那就是NSCache实例不能保证将值返回给您以前存储的键。当您尝试添加键值对时,如果它认为此时性能更重要,它甚至可能不存储键值对 对我来说,这意味着: 每个键必须“保存”足够的信息,以便在必要时生成值 NSCache的每个查询本质上只是一个键的形式,因此应该包含生成相应值所需的所有信息 从以上两点可以说,NSCache没有在键和值之间建立任何类型的关联的目的——用户必须能够独立于缓存生成值,使用NSCache的唯一目的不是“查找”某个值,

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

对我来说,这意味着:

  • 每个键必须“保存”足够的信息,以便在必要时生成值
  • NSCache的每个查询本质上只是一个键的形式,因此应该包含生成相应值所需的所有信息

  • 从以上两点可以说,NSCache没有在键和值之间建立任何类型的关联的目的——用户必须能够独立于缓存生成值,使用NSCache的唯一目的不是“查找”某个值,而只是为了用内存换取某个性能提升

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

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

    您创建包含所有这些信息的密钥的想法应该是可行的——只需记住将所有密钥存储在缓存之外的其他位置即可

    至于键,您可以创建一个非常简单的类,它只有几个属性(组成键的属性)、一个
    isEqual:
    hash
    方法,还可以创建一个初始值设定项,该初始值设定项为您的每个属性获取参数

    这需要非常少的代码,因为属性的访问器和IVAR是自动生成的,所以您真正需要编写的唯一一件事就是
    isEqual:
    方法(和
    hash


    这个类非常小,taylor专门为您需要它的特定情况而设计,在您将要使用它的.m文件的顶部声明并实现它是有意义的。这样,您就不会污染系统的其余部分。只需在.m文件的顶部添加类的
    @interface
    @implementation
    部分。

    仔细考虑后,我认为我搞错了一件事-NSCache中的键不一定需要保存生成值的所有信息。NSCache中的键可以起到与NSDictionary中相同的作用—一个查找值的唯一标识符。不过,唯一的区别是,您始终需要为NSCache制定备份计划B,以防之前添加的键值对被破坏

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

    NSDictionary

  • 为每个键
    K
    生成每个值
    V
    ,并将对添加到字典中
  • 使用
    K
  • NSCache

  • 使用
    K
  • 如果
    V==nil
    ,则生成值
    V
    ,并将该对添加到缓存中
  • 因此,几乎可以将任何NSDictionary转换为NSCache,只是转换后不能传递NSCache—您必须知道如何始终生成值,因此NSCache实例很可能是某个类中专用的私有属性

    对于我的问题,我决定使用这样的方法(
    self
    应该指向NSCache的一个子类,但我还没有测试它)


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

    “使用NSCache的唯一目的不是“查找”某些值,而是为了用内存换取一些性能提升。”缓存就是这样做的。基本上,如果您只需要键值关联,只需使用图像名称作为键的
    NSMutableDictionary
    。咳嗽它是
    相等:
    ,而不是
    相等:
    。如果我现在找不到明确的注释,但不需要使用
    散列
    ,我也会感到非常惊讶。我真的应该停止在匆忙中快速写答案。谢谢,更正了。哈希方法最重要的规则是:如果两个对象相等,则它们的哈希必须相同。理论上,让所有对象返回相同的哈希值是合法的,但会导致字典、集合、缓存等中的查找性能非常差。
    
    - (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;
    }