Programming

Objective-C 정적 클래스 레벨 변수

procodes 2020. 6. 18. 22:15
반응형

Objective-C 정적 클래스 레벨 변수


나는 고유 한 ID를 저장하는 클래스 영화를 가지고 있습니다. C #, Java 등에서 정적 int currentID를 정의 할 수 있으며 ID를 설정할 때마다 currentID를 늘릴 수 있으며 객체 수준이 아닌 클래스 수준에서 변경이 발생합니다. Objective-C에서이 작업을 수행 할 수 있습니까? 이에 대한 답을 찾는 것이 매우 어렵다는 것을 알았습니다.


문제 설명 :

  1. ClassA에 ClassB 클래스 변수가 있어야합니다.
  2. 프로그래밍 언어로 Objective-C를 사용하고 있습니다.
  3. Objective-C는 C ++처럼 클래스 변수를 지원하지 않습니다.

하나의 대안 :

Objective-C 기능을 사용하여 클래스 변수 동작 시뮬레이션

  1. classA.m 내에서 정적 변수를 선언 / 정의하면 classA 메소드 (및 classA.m에 넣은 모든 것)에 대해서만 액세스 할 수 있습니다.

  2. NSObject 초기화 클래스 메소드를 덮어 써서 정적 변수를 ClassB 인스턴스로 한 번만 초기화하십시오.

  3. 왜 NSObject initialize 메소드를 덮어 써야하는지 궁금 할 것입니다. 이 방법에 대한 Apple 문서는 다음과 같은 대답을 가지고 있습니다. "런타임은 클래스 바로 전에 한 번 또는 프로그램에서 상속 된 모든 클래스에 프로그램의 각 클래스로 초기화를 보냅니다. 클래스를 사용하지 않으면 호출 될 수 없습니다.) ".

  4. 모든 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

참고 문헌 :

  1. Objective-C와 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]

And then, when you want to set it:

[MyClass testHolder:testVal]

In the case you want to be able to set this pseudo-static-var to nil, you can declare testHolder as this:

+ (NSString*)testHolderSet:(BOOL)shouldSet newValue:(NSString*)_test {
    static NSString *test;

    if(shouldSet) {
        if(test != nil)
            [test release];
        test = [_test retain];
    }

    return test;
}

And two handy methods:

+ (NSString*)test {
    return [MyClass testHolderSet:NO newValue:nil];
}

+ (void)setTest:(NSString*)_test {
    [MyClass testHolderSet:YES newValue:_test];
}

Hope it helps! Good luck.


On your .m file, you can declare a variable as static:

static ClassName *variableName = nil;

Then you can initialize it on your +(void)initialize method.

Please note that this is a plain C static variable and is not static in the sense Java or C# consider it, but will yield similar results.


In your .m file, declare a file global variable:

static int currentID = 1;

then in your init routine, refernce that:

- (id) init
{
    self = [super init];
    if (self != nil) {
        _myID = currentID++; // not thread safe
    }
    return self;
}

or if it needs to change at some other time (eg in your openConnection method), then increment it there. Remember it is not thread safe as is, you'll need to do syncronization (or better yet, use an atomic add) if there may be any threading issues.


As pgb said, there are no "class variables," only "instance variables." The objective-c way of doing class variables is a static global variable inside the .m file of the class. The "static" ensures that the variable can not be used outside of that file (i.e. it can't be extern).


Here would be an option:

+(int)getId{
    static int id;
    //Do anything you need to update the ID here
    return id;
}

Note that this method will be the only method to access id, so you will have to update it somehow in this code.


(Strictly speaking not an answer to the question, but in my experience likely to be useful when looking for class variables)

A class method can often play many of the roles a class variable would in other languages (e.g. changed configuration during tests):

@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

Now, an object of class MyCls calls Resource:changeSomething: with the string @"Something general" upon a call to doTheThing:, but an object derived from MySpecialCase with the string @"Something specific".


u can rename the class as classA.mm and add C++ features in it.


Another possibility would be to have a little NSNumber subclass singleton.

참고URL : https://stackoverflow.com/questions/1063229/objective-c-static-class-level-variables

반응형