@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
现在哪一个是正确的?为什么?
答案 0 :(得分:5)
如您所知,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];
}
}
请注意,在第二个示例中,您不应该从实例的-dealloc
方法中释放“class”变量。如果你有多个对象的实例,这会留下一个糟糕的悬空指针,并且无论如何都会破坏“类”变量的目的。通常,当您使用此模式时,您将“泄漏”(对于某些泄漏定义)类变量值,这没关系。
答案 1 :(得分:0)
类变量通常都是不好的样式。
然而,其他答案的替代方法是为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