Ассоциативные ссылки похоже, что они добьются цели. Вы можете по существу привязать некоторое хранилище к самому объекту класса. (Я использую NSString
здесь вместо словарей, которые вы хотите использовать, только для демонстрации.)
суперкласс:
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Stuper : NSObject
// Accessor method for the "class variable"
+ (NSString *) str;
// Analog to your +localStorePath
+ (NSString *) quote;
@end
#import "Stuper.h"
// The doc suggests simply using the address of a static variable as the key.
// This works fine, even though every class is (as in your problem) using
// the same key, because we are associating to a different class each time.
static char key;
@implementation Stuper
+ (NSString *) str {
NSString * s = objc_getAssociatedObject(self, &key);
if( !s ){
s = [self quote];
// You'll probably want to use OBJC_ASSOCIATION_RETAIN for your dictionary.
// self inside a class method is the class object; use that as
// the associator. The string is now tied to the associator, i.e.,
// has the same lifetime.
objc_setAssociatedObject(self, &key, s, OBJC_ASSOCIATION_COPY);
}
return s;
}
+ (NSString *) quote {
return @"It was the best of times, it was the worst of times.";
}
@end
<ч /> <ч />
Подкласс:
#import "Stuper.h"
@interface Stub : Stuper @end
#import "Stub.h"
@implementation Stub
+ (NSString *) quote {
return @"Call me Ishmael.";
}
@end
<ч /> <ч />
Пробуем это:
#import <Foundation/Foundation.h>
#import "Stuper.h"
#import "Stub.h"
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"%@", [Stuper str]);
NSLog(@"%@", [Stub str]);
[pool drain];
return 0;
}
Каждый объект класса теперь имеет свою собственную строку, связанную с ним.
2011-12-05 23: 11: 09.031 SubClassVariables [36254: 903] Это были лучшие времена, это были худшие времена.
2011-12-05 23: 11: 09.034 Переменные подкласса [36254: 903] Зовите меня Измаил.
Единственным недостатком здесь является то, что вам придется вызывать метод доступа каждый раз, когда вы хотите объект; у вас нет указателя, который вы можете использовать напрямую. Вы можете также вызвать objc_getAssociatedObject
в суперклассе в качестве средства доступа, поскольку он имеет доступ к key
.