简体   繁体   English

Objective-C和内存管理中的类变量

[英]class variables in objective-c and memory management

@implementation ProductController


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

and

@implementation ProductController


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

Now which one is correct?and why? 现在哪一个是正确的?为什么?

As you seem to understand, there are no "class variables" in Obj-C. 如您所了解,Obj-C中没有“类变量”。 The workaround is just a C-style (global, or file-scoped) variable that you set up similarly to how you've shown above. 解决方法只是一个C样式(全局或文件作用域)变量,您可以按照上面的显示方法进行类似的设置。 First off, you should use file scope for these variables by marking them with the static keyword: 首先,您应该通过使用static关键字标记这些变量来使用文件作用域:

static NSString *areaName = nil;

You might also consider using a convention like FirstLetterUppercase to indicate the scope difference. 您可能还考虑使用诸如FirstLetterUppercase类的FirstLetterUppercase来表示范围差异。

As for memory management, you can treat it exactly like an instance variable, but one that never goes away forever: 至于内存管理,您可以将其完全视为一个实例变量,但是它永远不会消失:

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

Note that in your second example, you should NOT release the "class" variable from an instance's -dealloc method. 请注意,在第二个示例中,不应从实例的-dealloc方法释放“ class”变量。 If you have more than one instance of the object, this leaves a bad dangling pointer, and defeats the purpose of the "class" variable anyways. 如果对象有一个以上的实例,则将留下一个不良的悬空指针,并且始终无法达到“ class”变量的目的。 Generally, when you use this pattern, you'll "leak" (for some definition of leak) the class variable value, and that's OK. 通常,使用这种模式时,您将“泄漏”(为泄漏的某种定义)类变量值,这没关系。

class variables are generally bad style. 类变量通常是不良样式。

nevertheless, an alternative to other answers would be to create a static dictionary for your lib/app's class variables. 但是,替代其他答案的方法是为lib / app的类变量创建静态字典。 a very primitive implementation would take this form: 一个非常原始的实现将采用以下形式:

// 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM