переменные класса в target-c и управлении памятью - PullRequest
0 голосов
/ 22 августа 2011
@implementation ProductController


NSString *areaName = nil;
+ (void)setAreaName:(NSString *)areaName_ {
    areaName = areaName_;
}
@end

и

@implementation ProductController


NSString *areaName = nil;
+ (void)setAreaName:(NSString *)areaName_ {
    if(areaName_ != areaName) {
        [areaName release];
        areaName = [areaName_ copy];
    }
}
- (void)dealloc {
     [areaName release];
}
@end

Теперь какой из них правильный? И почему?

Ответы [ 2 ]

5 голосов
/ 22 августа 2011

Как вы, похоже, понимаете, в Obj-C нет "переменных класса". Обходной путь - это просто переменная в стиле C (глобальная, или область действия файла), которую вы устанавливаете аналогично тому, как вы показали выше. Прежде всего, вы должны использовать область видимости для этих переменных, пометив их ключевым словом static:

static NSString *areaName = nil;

Вы также можете рассмотреть возможность использования соглашения, такого как FirstLetterUppercase, для указания разницы в области видимости.

Что касается управления памятью, вы можете обращаться с ним точно так же, как с переменной экземпляра, но она никогда не исчезнет навсегда:

static NSString *AreaName = nil;
+ (void)setAreaName:(NSString *)name {
    if (![name isEqualToString:AreaName]) {
        [AreaName release];
        AreaName = [name copy];
    }
}

Обратите внимание, что во втором примере вы НЕ должны освобождать переменную "class" из экземпляра -dealloc метода. Если у вас есть более одного экземпляра объекта, это оставляет плохой висячий указатель и в любом случае побеждает назначение переменной «class». Обычно, когда вы используете этот шаблон, вы «утечете» (для некоторого определения утечки) значение переменной класса, и это нормально.

0 голосов
/ 22 августа 2011

переменные класса, как правило, плохой стиль.

тем не менее, альтернативой другим ответам будет создание статического словаря для переменных класса вашего lib / app.очень примитивная реализация будет иметь следующий вид:

// MONLibraryClassVariable.h

extern id MONLibraryClassVariableGetObjectForKey(NSString * key);
extern void MONLibraryClassVariableSetObjectForKey(id<NSObject> object, NSString * key);

// MONLibraryClassVariable.m

/* @todo make all this thread safe */

static NSMutableDictionary * MONLibraryClassVariables_ = nil;

id MONLibraryClassVariableGetObjectForKey(NSString * key) {
    return [MONLibraryClassVariables_ objectForKey:key];
}

void MONLibraryClassVariableSetObjectForKey(id<NSObject> object, NSString * key) {

    if (nil == MONLibraryClassVariables_) {
        MONLibraryClassVariables_ = [NSMutableDictionary new];
    }

    [MONLibraryClassVariables_ setObject:object forKey:key];
}

// ProductController.m

static NSString * const ProductController_KEY_areaName = @"ProductController.areaName";

@implementation ProductController

+ (void)setAreaName:(NSString *)inAreaName {
    MONLibraryClassVariableSetObjectForKey([[inAreaName copy] autorelease], ProductController_KEY_areaName);
}

- (void)dealloc {
// nope [areaName release];
    [super dealloc];
}

@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...