Cocoa에는 이런 일이 있다는 것을 알고 있습니다. 예를 들어 다음을 생성 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
두 값은 다음을 수행합니다.
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”-표현이 잘못된 이유)?
답변
답변
enum DownloadViewStatus {
FileNotDownloaded = 1,
FileDownloading = 2,
FileDowloaded = 4
};
이렇게하면 비트 OR 및 AND를 효과적으로 수행 할 수 있습니다.
답변
가독성을 높이기 위해 비트 마스크 검사에 사용할 수있는 유용한 기능입니다.
BOOL bitmaskContains(NSUInteger bitmask, NSUInteger contains) {
return (bitmask & contains) != 0;
}