iOS缓存库无法正常工作

时间:2011-12-07 20:15:41

标签: objective-c ios caching

我为我的iOS应用程序构建了一个非常简单的缓存类,但它似乎保存了给它的数据,它永远无法检索它。 My Cache系统应该通过创建一个CachedObject来工作,该CachedObject存储要缓存的Object,密钥和到期日期。然后它应该归档该对象并保存到名为key.cache的文件。

Cache.h

    #import <Foundation/Foundation.h>

    @interface Cache : NSObject

    +(void)setValue:(NSObject<NSCoding> *)value forKey:(NSString *)key expires:(NSDate *)expire;

    +(NSObject<NSCoding> *)getValueFromKey:(NSString *)key;

    @end

Cache.m

    #import "Cache.h"
    #import "CachedObject.h"
    #define CACHE_LOCATION @"Library/test"

    @implementation Cache

    +(void)setValue:(NSObject<NSCoding> *)value forKey:(NSString *)key expires:(NSDate *)expire
    {
        if ((value == nil) || (key == nil))
        {
            return;
        }
        CachedObject *obj = [[CachedObject alloc] initWithObject:value expires:expire forKey:key];
        NSError *error;
        if (![[NSFileManager defaultManager] createDirectoryAtPath:CACHE_LOCATION withIntermediateDirectories:YES attributes:nil error:&error])
        {
            [error release];
            return;
        }
        NSString *fileName = [[NSString alloc] initWithFormat:@"%@.cache", key];
        NSString *fileFullPath = [CACHE_LOCATION stringByAppendingPathComponent:fileName];
        [NSKeyedArchiver archiveRootObject:obj toFile:fileFullPath];
        [fileName release];
        [obj release];
    }

    +(NSObject<NSCoding> *)getValueFromKey:(NSString *)key
    {
        NSString *fileName = [[NSString alloc] initWithFormat:@"%@.cache", key];
        NSString *fileFullPath = [CACHE_LOCATION stringByAppendingPathComponent:fileName];
        CachedObject *obj = [NSKeyedUnarchiver unarchiveObjectWithFile:fileFullPath];
        NSDate *today = [NSDate date];
        if ((obj != nil) && (obj.expires != nil) && ([obj.expires compare:today] != NSOrderedAscending))
        {
            obj = nil;
        }
        [fileName release];
        if (obj != nil)
        {
            obj = [obj autorelease];
        }
        return obj;
    }

    @end

CachedObject.h

    #import <Foundation/Foundation.h>

    @interface CachedObject : NSObject<NSCoding>
    {
        NSObject<NSCoding> *_object;
        NSDate       *_expires;
        NSString     *_key;
    }

    @property (readonly) NSObject<NSCoding> *object;
    @property (readonly) NSDate       *expires;
    @property (readonly) NSString     *key;

    -(id)initWithObject:(NSObject<NSCoding> *)aObject expires:(NSDate *)aExpires forKey:(NSString *)aKey;

    @end

CachedObject.m

    #import "CachedObject.h"
    #define EXPIRE_KEY @"expires"
    #define KEY_KEY @"key"

    @implementation CachedObject

    @synthesize object = _object;
    @synthesize expires = _expires;
    @synthesize key = _key;

    -(void)encodeWithCoder:(NSCoder *)aCoder
    {
        [_object encodeWithCoder:aCoder];
        [aCoder encodeObject:_expires forKey:EXPIRE_KEY];
        [aCoder encodeObject:_key forKey:KEY_KEY];
    }

    -(id)initWithCoder:(NSCoder *)aDecoder
    {
        if (self = [super init])
        {
            _object = [_object initWithCoder:aDecoder];
            if (self.object == nil)
            {
                return nil;
            }
            _expires = [[aDecoder decodeObjectForKey:EXPIRE_KEY] retain];
            _key = [[aDecoder decodeObjectForKey:KEY_KEY] retain];
        }
        return self;
    }

    -(id)initWithObject:(NSObject<NSCoding> *)aObject expires:(NSDate *)aExpires forKey:(NSString *)aKey
    {
        if (self = [super init])
        {
            _object = aObject;
            _expires = aExpires;
            _key = aKey;
        }
        return self;
    }

    @end

2 个答案:

答案 0 :(得分:4)

根据NSComparator文档,

NSArray *sortedArray = [array sortedArrayUsingComparator: ^(id obj1, id obj2) {

    if ([obj1 integerValue] > [obj2 integerValue]) {
        return (NSComparisonResult)NSOrderedDescending;
    }

    if ([obj1 integerValue] < [obj2 integerValue]) {
        return (NSComparisonResult)NSOrderedAscending;
    }
    return (NSComparisonResult)NSOrderedSame;
}];

您需要在NSOrderedAscending方法中将NSOrderedDescending替换为-getValueForKey:

答案 1 :(得分:0)

我认为部分问题可能是您在_object内序列化CachedObject.m实例变量的方式(也许任何NSCoding专家都可能证明我错了?)

我认为不是:

-(void)encodeWithCoder:(NSCoder *)aCoder
    {
        [_object encodeWithCoder:aCoder];
        [aCoder encodeObject:_expires forKey:EXPIRE_KEY];
        [aCoder encodeObject:_key forKey:KEY_KEY];
    }

您想使用:

-(void)encodeWithCoder:(NSCoder *)aCoder
    {
        [aCoder encodeObject:_object forKey:OBJECT_KEY];
        [aCoder encodeObject:_expires forKey:EXPIRE_KEY];
        [aCoder encodeObject:_key forKey:KEY_KEY];
    }

由于您希望将_object视为实例变量,与您的_expires_key对象类似。

旁注:自动释放对象时,您不需要这样做:

if (obj != nil)
{
    obj = [obj autorelease];
}
return obj;

你可以这样做:

return [obj autorelease];