Answers:
问题说明:
一种选择:
使用Objective-C功能模拟类变量行为
在classA.m中声明/定义一个静态变量,以便只能对classA方法(以及放在classA.m中的所有内容)进行访问。
覆盖NSObject初始化类方法,以使用ClassB实例仅对静态变量进行一次初始化。
您会想知道,为什么我应该覆盖NSObject的initialize方法。Apple文档中有关此方法的答案是:“运行时正好在该类或从其继承的任何类从程序内部发送其第一条消息之前,一次将初始化发送给程序中的每个类。如果不使用该类,则可能永远不会被调用。)”。
随时在任何ClassA类/实例方法中使用静态变量。
代码示例:
文件:classA.m
static ClassB *classVariableName = nil;
@implementation ClassA
...
+(void) initialize
{
if (! classVariableName)
classVariableName = [[ClassB alloc] init];
}
+(void) classMethodName
{
[classVariableName doSomething];
}
-(void) instanceMethodName
{
[classVariableName doSomething];
}
...
@end
参考文献:
initialize
每个类(超类先于子类)被调用一次,但是如果子类没有重写initialize
,则父类initialize
将被再次调用。因此,如果您不希望该代码执行两次,则需要一个保护措施。请参阅Apple的Objective-C文档中的初始化类对象。
从Xcode 8开始,您可以在Obj-C中定义类属性。已添加它以与Swift的静态属性进行互操作。
现在,Objective-C支持与Swift类型属性互操作的类属性。它们声明为:@property(类)NSString * someStringProperty;。它们永远不会合成。(23891898)
这是一个例子
@interface YourClass : NSObject
@property (class, nonatomic, assign) NSInteger currentId;
@end
@implementation YourClass
static NSInteger _currentId = 0;
+ (NSInteger)currentId {
return _currentId;
}
+ (void)setCurrentId:(NSInteger)newValue {
_currentId = newValue;
}
@end
然后,您可以像这样访问它:
YourClass.currentId = 1;
val = YourClass.currentId;
这是一篇非常有趣的说明性文章,我以此为参考来编辑此旧答案。
2011答案:(不要使用它,这很糟糕)
如果您确实真的不想声明全局变量,则可以使用另一个选项,也许不是很传统:-),但是可以使用...您可以这样声明“ get&set”方法,并在其中包含一个静态变量:
+ (NSString*)testHolder:(NSString*)_test {
static NSString *test;
if(_test != nil) {
if(test != nil)
[test release];
test = [_test retain];
}
// if(test == nil)
// test = @"Initialize the var here if you need to";
return test;
}
因此,如果您需要获取值,则只需调用:
NSString *testVal = [MyClass testHolder:nil]
然后,当您要设置它时:
[MyClass testHolder:testVal]
如果您希望能够将此伪静态变量设置为nil,则可以这样声明testHolder
:
+ (NSString*)testHolderSet:(BOOL)shouldSet newValue:(NSString*)_test {
static NSString *test;
if(shouldSet) {
if(test != nil)
[test release];
test = [_test retain];
}
return test;
}
还有两种方便的方法:
+ (NSString*)test {
return [MyClass testHolderSet:NO newValue:nil];
}
+ (void)setTest:(NSString*)_test {
[MyClass testHolderSet:YES newValue:_test];
}
希望能帮助到你!祝好运。
.m
文件访问它,我认为在Class.m
文件内将其“全局”是可以的。
(严格来说,这不是问题的答案,但以我的经验,查找类变量时可能会很有用)
类方法通常可以扮演类变量在其他语言中的许多角色(例如,在测试过程中更改配置):
@interface MyCls: NSObject
+ (NSString*)theNameThing;
- (void)doTheThing;
@end
@implementation
+ (NSString*)theNameThing { return @"Something general"; }
- (void)doTheThing {
[SomeResource changeSomething:[self.class theNameThing]];
}
@end
@interface MySpecialCase: MyCls
@end
@implementation
+ (NSString*)theNameThing { return @"Something specific"; }
@end
现在,class对象在MyCls
调用时Resource:changeSomething:
使用字符串@"Something general"
进行调用doTheThing:
,而对象从MySpecialCase
string 派生@"Something specific"
。