programing

Objective-C에서의 선언 및 체크/비교(비트마스크-) Enum

minecode 2022. 10. 21. 21:34
반응형

Objective-C에서의 선언 및 체크/비교(비트마스크-) Enum

당신은 코코아에 이런 것이 있다는 것을 알고 있다. 예를 들어 당신은 그것을 만들 수 있다.UIView다음 작업을 수행합니다.

view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

나는 단골이 있다.UIView여러 개의 상태를 가지고 있습니다.enum다음과 같습니다.

enum DownloadViewStatus {
  FileNotDownloaded,
  FileDownloading,
  FileDownloaded
};

생성된 각 서브뷰에 대해 다음 서브뷰를 설정합니다.tag:subview1.tag = FileNotDownloaded;

다음으로 뷰 상태에 대한 커스텀세터가 준비되어 있습니다.이 세터는 다음과 같습니다.

for (UIView *subview in self.subviews) {
  if (subview.tag == viewStatus)
    subview.hidden = NO;
  else
    subview.hidden = YES;
}

하지만 제가 하려는 것은, 이것을 허용하는 것입니다.

subview1.tag = FileNotDownloaded | FileDownloaded;

그래서 나의subview1두 가지 상태로 표시됩니다.현재 이 두 주 중 어느 주에도 나타나지 않고 있습니다.|연산자가 두 개의 열거값을 추가한 것 같습니다.

그렇게 할 수 있는 방법이 있나요?

비트마스크 선언:

절대값을 할당하는 방법(1,2,4, …) 다음과 같이 비트마스크를 선언할 수 있습니다.

typedef enum : NSUInteger {
  FileNotDownloaded = (1 << 0), // => 00000001
  FileDownloading   = (1 << 1), // => 00000010
  FileDownloaded     = (1 << 2)  // => 00000100
} DownloadViewStatus;

또는 최신 ObjC를 사용하여NS_OPTIONS/NS_ENUM매크로:

typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) {
  FileNotDownloaded = (1 << 0), // => 00000001
  FileDownloading   = (1 << 1), // => 00000010
  FileDownloaded    = (1 << 2)  // => 00000100
};

(후자에 대한 자세한 내용은 Abizern의 답변을 참조하십시오.)

비트마스크의 개념은 (일반적으로) 단일 비트세트로 각 열거값을 정의하는 것입니다.

이런 이유로OR는, 다음의 2개의 값을 입력합니다.

DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101

이는 다음과 같습니다.

  00000001 // FileNotDownloaded
| 00000100 // FileDownloaded
----------
= 00000101 // (FileNotDownloaded | FileDownloaded)

비트 마스크 비교:

비트마스크와 대조할 때 주의해야 할 점은 다음과 같습니다.

정확한 동일성 확인:

상태가 다음과 같이 초기화된다고 가정합니다.

DownloadViewStatus status = FileNotDownloaded | FileDownloaded; // => 00000101

체크하고 싶은 경우status 동등. FileNotDownloaded, 다음을 사용할 수 있습니다.

BOOL equals = (status == FileNotDownloaded); // => false

이는 다음과 같습니다.

   00000101 // (FileNotDownloaded | FileDownloaded)
== 00000100 // FileDownloaded
-----------
=  00000000 // false

"구성원 자격" 확인 중:

체크하고 싶은 경우status단지 포함하다 FileNotDownloaded, 다음을 사용해야 합니다.

BOOL contains = (status & FileNotDownloaded) != 0; // => true

   00000101 // (FileNotDownloaded | FileDownloaded)
&  00000100 // FileDownloaded
-----------
=  00000100 // FileDownloaded
!= 00000000 // 0
-----------
=  00000001 // 1 => true

미묘한 차이(그리고 현재의 "if" 표현이 잘못된 이유)를 알 수 있습니까?

@Regexident는 훌륭한 답변을 제공했습니다만, 다음과 같이 Enumerated 옵션을 선언하는 최신 Objective-C 방식을 언급해야 합니다.NS_OPTIONS:

typedef NS_OPTIONS(NSUInteger, DownloadViewStatus) {
  FileNotDownloaded = 0,
  FileDownloading   = 1 << 0,
  FileDownloaded    = 1 << 1
};

상세 레퍼런스:

enum DownloadViewStatus {
  FileNotDownloaded = 1,
  FileDownloading = 2,
  FileDowloaded = 4
};

이렇게 하면 비트 단위 OR과 AND를 효과적으로 수행할 수 있습니다.

비트 마스크 검사에 사용할 수 있는 유용한 기능으로 가독성을 향상시킵니다.

BOOL bitmaskContains(NSUInteger bitmask, NSUInteger contains) {
    return (bitmask & contains) != 0;
}

언급URL : https://stackoverflow.com/questions/16166895/declaring-and-checking-comparing-bitmask-enums-in-objective-c

반응형