Пользовательский одиночный класс KeyValuePair против NSMutableDictionary - PullRequest
2 голосов
/ 27 сентября 2011

Я попал в ситуацию, когда мне пришлось написать цикл с большим количеством итераций, и в этом цикле у меня был объект NSData, который мне пришлось связать с ключом.Это привело меня к поиску простого класса target-c _KeyValuePair_, но я не смог найти ни одного, поэтому я написал свой собственный.Теперь мне любопытно посмотреть, есть ли какая-то выгода от использования NSMutableDictinoary, содержащего только 1 клавишу и значение.Попробовав и то и другое на протяжении всего моего проекта, я не вижу особой разницы в пользовательском интерфейсе приложения или в приложении Instruments Time Profiler.

Итак, мои вопросы:

  • Может ли отдельный класс kvpair быть более эффективным, чем NSMutableDictionary
  • Может ли NSMutableDictвыделять больший объем пространства по умолчанию, чем это делает
  • Существует ли на самом деле стандартная пара пар значений-ключей, которую я только что пропустил

Некоторый код:

for (int i = 0, count = [photoUrls count]; i < count; ++i) {
    // Example usage of the kvp class
    NSMutableDictionary *imageRequest = [[NSMutableDictionary alloc] init];
    JHKeyValuePair *kvPair = [[JHKeyValuePair alloc] initWithKey:@"DAILY" andValue:[NSNumber numberWithInt:i];
    [imageRequest setObject:self forKey:@"delegate"];
    [imageRequest setObject:kvPair forKey:@"userInfo"];
    [kvPair release];
    [imageRequest setObject:[dailySpecialData objectForKey:@"IMAGE_URL"] forKey:@"url"];
    [imageDownloader addDownloadRequestToQueue:imageRequest];
    [imageRequest release];
}

JHKeyValuePair.h

@interface JHKeyValuePair : NSObject {
    id key;
    id value;
}

@property (nonatomic, retain) id key;
@property (nonatomic, retain) id value;

- (id)initWithKey:(id)aKey andValue:(id)aValue;

@end

JHKeyValuePair.m

#import "JHKeyValuePair.h"

@implementation JHKeyValuePair

@synthesize key;
@synthesize value;

- (id)initWithKey:(id)aKey andValue:(id)aValue {
    if ((self = [super init])) {
        key   = [aKey retain];
        value = [aValue retain];
    }
    return self;
}

- (void)dealloc {
    [key release], key = nil;
    [value release], value = nil;
    [super dealloc];
}

- (id)copyWithZone:(NSZone *)zone {
    JHKeyValuePair *copy = [[JHKeyValuePair allocWithZone:zone] init];
    [copy setKey:self.key];
    [copy setValue:self.value];
    return copy;
}

- (BOOL)isEqual:(id)anObject {
    BOOL ret;
    if (self == anObject) {
        ret = YES;
    } else if (![anObject isKindOfClass:[JHKeyValuePair class]]) {
        ret = NO;
    } else {
        ret = [key isEqual:((JHKeyValuePair *)anObject).key] && [value isEqual:((JHKeyValuePair *)anObject).value];
    }
    return ret;
}

@end

Изменить, чтобы исправить первоначальное объяснение.Кажется, я получил отвлеченную середину и никогда не возвращался, чтобы закончить.

1 Ответ

1 голос
/ 27 сентября 2011

Если вы действительно хотите получить скорость, вы делаете много ненужных сохраняемых выпусков, которые, вероятно, не нужны каждый раз, когда вы устанавливаете свой ключ / значения. Если вы используете структуру и некоторый базовый код на c, вы можете достичь чего-то немного быстрее, но вы жертвуете простым и последовательным управлением памятью, которое вы получаете, выполняя это целевым образом.

typedef struct {
    id key;
    id value;
} Pair;

BOOL isEqual(Pair a, Pair b); //...

// You will need to clean up after yourself though:
void PairRelease(Pair p) {
    [p.key release];
    [p.value release];
}
...