iOS Cache Library не работает - PullRequest
       2

iOS Cache Library не работает

1 голос
/ 08 декабря 2011

Я создал ОЧЕНЬ простой класс кэширования для своего приложения для iOS, но, несмотря на то, что он, похоже, сохраняет данные, переданные ему, он никогда не сможет получить его. Моя система кэширования должна работать путем создания объекта CachedObject, в котором хранится объект для кэширования, ключ и дата окончания срока действия. Затем он должен заархивировать этот объект и сохранить в файл с именем 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 ]

4 голосов
/ 08 декабря 2011

Согласно 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: методе.

0 голосов
/ 08 декабря 2011

Я думаю, что часть проблемы может заключаться в том, как вы сериализуете свою _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];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...