说我有一个类方法
+ (double)function:(id)param1 :(id)param2
{
// I want to memoize this like...
static NSMutableDictionary* cache = nil;
//
// test if (param1,param2) is in cache and return cached value, etc. etc
//
}
谢谢!!
说我有一个类方法
+ (double)function:(id)param1 :(id)param2
{
// I want to memoize this like...
static NSMutableDictionary* cache = nil;
//
// test if (param1,param2) is in cache and return cached value, etc. etc
//
}
谢谢!!
如果您想创建一次缓存并对其进行检查,我通常使用一种+initialize
方法。这个方法在第一条消息发送到类之前被调用,所以缓存会在被调用之前创建+function::
(顺便说一下,这是一个糟糕的选择器名称)。在这种情况下,我通常在 .m 文件中声明缓存变量,但在方法定义中声明它也可能有效。
编辑:应OP的要求添加一个示例:
// MyClass.m
static NSMutableDictionary* cache;
+ (void) initialize {
cache = [[NSMutableDictionary alloc] init];
}
+ (double) cachedValueForParam1:(id)param1 param2:(id)param2 {
// Test if (param1,param2) is in cache and return cached value.
}
显然,如果缓存中不存在某个值,您应该有一些添加该值的代码。另外,我不知道您打算如何组合param1
并param2
作为缓存的键,或者您将如何存储该值。(也许+[NSNumber numberWithDouble:]
和-[NSNumber doubleValue]
?)在实施这样的策略之前,您需要确保您了解字典查找。
我使用类似下面的东西。与@Quinn Taylor 发布的版本不同,此版本具有以下属性:
NSAutoreleasePool
以保证池存在。在处理“启动”之类的代码时,最好假设最坏的情况。如果游泳池已经存在,则无害。cache
一次:
+initialize
多次(可能通过子分类发生)。+initialize
,cache
都保证只创建一次。“赢得”原子 CAS 的线程保留cache
,“松散”autorelease
他们的尝试的线程。如果你想非常保守,你可以添加断言检查两者pool
和initCache
不是NULL
。另请注意,这并不能确保cache
它在创建后以多线程安全方式使用。
#include <libkern/OSAtomic.h>
static NSMutableDictionary *cache;
+ (void)initialize
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableDictionary *initCache = [[[NSMutableDictionary alloc] init] autorelease];
_Bool didSwap = false;
while((cache == NULL) && ((didSwap = OSAtomicCompareAndSwapPtrBarrier(NULL, initCache, (void * volatile)&cache)) == false)) { /* Allows for spurious CAS failures. */ }
if(didSwap == true) { [cache retain]; }
[pool release];
pool = NULL;
}
根据您要执行的操作以及线程安全是否是一个问题,您可能还需要考虑一个单例类,如对前面问题的回答。