[英]How to import/use swift static library/framework in to .mm class extension in Xcode Objective-C Project
[英]Memoization in static Objective-C class
说我有一个类方法
+ (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
(可能通过子类发生)。 +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;
}
根据您要执行的操作以及线程安全性是否是一个问题,您可能还想考虑一个单例类,如对此先前问题的回答中所示 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.