속성 선언에서 원자 및 nonatomic
atomic
무엇을 의미합니까?
@property(nonatomic, retain) UITextField *userName; @property(atomic, retain) UITextField *userName; @property(retain) UITextField *userName;
이 세 가지의 운영상의 차이점은 무엇입니까?
질문자 :Alex Wayne
속성 선언에서 원자 및 nonatomic
atomic
무엇을 의미합니까?
@property(nonatomic, retain) UITextField *userName; @property(atomic, retain) UITextField *userName; @property(retain) UITextField *userName;
이 세 가지의 운영상의 차이점은 무엇입니까?
마지막 두 개는 동일합니다. "atomic"은 기본 동작입니다( 실제로 키워드가 아니라는 점에 유의하십시오. 이는 이 없을 때만 지정됩니다 -- nonatomic
atomic
은 llvm/clang의 최근 버전에서 키워드로 추가되었습니다).
메소드 구현을 @synthesizing한다고 가정하면 원자성 대 비 원자성은 생성된 코드를 변경합니다. 자신만의 setter/getter를 작성하는 경우 atomic/nonatomic/retain/assign/copy는 단지 권고 사항일 뿐입니다. (참고: @synthesize는 이제 LLVM의 최신 버전에서 기본 동작입니다. 또한 인스턴스 변수를 선언할 필요도 없습니다. 또한 자동으로 합성되며 우발적인 직접 액세스를 방지하기 위해 이름 앞에 _
"원자"를 사용하면 합성된 setter/getter는 다른 스레드의 setter 활동에 관계없이 전체 값이 항상 getter에서 반환되거나 setter에 의해 설정되도록 합니다. 즉, 스레드 A가 getter의 중간에 있고 스레드 B가 setter를 호출하면 실제 실행 가능한 값(자동 릴리스된 개체, 가장 가능성이 높음)이 A의 호출자에게 반환됩니다.
nonatomic
에서는 그러한 보장이 없습니다. 따라서 nonatomic
은 "atomic"보다 훨씬 빠릅니다.
"원자"가 하지 않는 것은 스레드 안전성에 대한 보장을 하지 않는 것입니다. 스레드 A가 다른 값으로 setter를 호출하는 스레드 B 및 C와 동시에 getter를 호출하는 경우 스레드 A는 세 가지 값 중 하나를 반환할 수 있습니다. 마찬가지로, 객체는 B 또는 C의 값으로 끝날 수 있습니다. 말할 방법이 없습니다.
다중 스레드 프로그래밍의 주요 과제 중 하나인 데이터 무결성 보장은 다른 방법으로 달성됩니다.
여기에 추가:
atomicity
성은 또한 여러 종속 속성이 사용 중일 때 스레드 안전성을 보장할 수 없습니다.
고려하다:
@property(atomic, copy) NSString *firstName; @property(atomic, copy) NSString *lastName; @property(readonly, atomic, copy) NSString *fullName;
setFirstName:
을 호출한 다음 setLastName:
을 호출하여 객체의 이름을 변경할 수 있습니다. 그 동안 스레드 B는 fullName
을 호출할 수 있으며 이전 성이 결합된 새 이름을 수신합니다.
이 문제를 해결하려면 트랜잭션 모델 이 필요합니다. 즉, 종속 속성이 업데이트되는 동안 fullName
대한 액세스를 제외할 수 있는 다른 종류의 동기화 및/또는 제외입니다.
이것은 Apple의 문서 에 설명되어 있지만 아래는 실제로 일어나는 일의 몇 가지 예입니다.
"atomic" 키워드가 없다는 점에 유의하십시오. "nonatomic"을 지정하지 않으면 속성이 원자적이지만 "atomic"을 명시적으로 지정하면 오류가 발생합니다.
"nonatomic"을 지정하지 않으면 속성은 atomic이지만 원하는 경우 최신 버전에서 명시적으로 "atomic"을 지정할 수 있습니다.
//@property(nonatomic, retain) UITextField *userName; //Generates roughly - (UITextField *) userName { return userName; } - (void) setUserName:(UITextField *)userName_ { [userName_ retain]; [userName release]; userName = userName_; }
이제 원자 변형은 조금 더 복잡합니다.
//@property(retain) UITextField *userName; //Generates roughly - (UITextField *) userName { UITextField *retval = nil; @synchronized(self) { retval = [[userName retain] autorelease]; } return retval; } - (void) setUserName:(UITextField *)userName_ { @synchronized(self) { [userName_ retain]; [userName release]; userName = userName_; } }
기본적으로 원자 버전은 스레드 안전성을 보장하기 위해 잠금을 취해야 하며 또한 객체의 참조 카운트(및 균형을 맞추기 위한 자동 릴리스 카운트)를 충돌하여 객체가 호출자에 대해 존재하도록 보장합니다. 그렇지 않으면 다른 스레드가 값을 설정하여 참조 횟수가 0으로 떨어지는 경우 잠재적 경쟁 조건입니다.
속성이 스칼라 값인지 객체인지, 그리고 유지, 복사, 읽기 전용, 비원자 등이 상호 작용하는 방식에 따라 실제로 이러한 것들이 작동하는 방식의 다양한 변형이 있습니다. 일반적으로 속성 합성기는 모든 조합에 대해 "올바른 일"을 수행하는 방법만 알고 있습니다.
차이점을 이해하는 가장 좋은 방법은 다음 예를 사용하는 것입니다.
이 "이름"이라는 원자 문자열 속성이며, 당신이 호출하면 가정 [self setName:@"A"]
스레드 A에서 호출 [self setName:@"B"]
스레드 B에서, 그리고 전화 [self name]
에서 스레드 C에서 다른 스레드의 모든 작업은 직렬로 수행됩니다. 즉, 한 스레드가 setter 또는 getter를 실행하면 다른 스레드가 대기합니다.
이렇게 하면 "name" 속성을 안전하게 읽고 쓸 수 있지만 다른 스레드 D가 [name release]
동시에 호출하면 여기에 관련된 setter/getter 호출이 없기 때문에 이 작업이 충돌을 일으킬 수 있습니다. 이는 개체가 읽기/쓰기 안전(ATOMIC)이지만 다른 스레드가 개체에 모든 유형의 메시지를 동시에 보낼 수 있으므로 스레드로부터 안전하지 않음을 의미합니다. 개발자는 이러한 개체에 대한 스레드 안전성을 보장해야 합니다.
"name" 속성이 원자가 아닌 경우 위의 예에 있는 모든 스레드(A,B, C 및 D)가 동시에 실행되어 예측할 수 없는 결과를 생성합니다. 원자의 경우 A, B 또는 C 중 하나가 먼저 실행되지만 D는 여전히 병렬로 실행할 수 있습니다.
구문과 의미는 이 질문에 대한 다른 훌륭한 답변에 의해 이미 잘 정의되어 있습니다. 실행 및 성능 이 잘 나와있지 않아 답변을 추가하겠습니다.
이 3가지의 기능적 차이점은 무엇입니까?
저는 항상 atomic을 매우 흥미로운 기본값으로 간주했습니다. 우리가 작업하는 추상화 수준에서 100% 스레드 안전성을 달성하기 위한 수단으로 클래스의 원자적 속성을 사용하는 것은 매우 어려운 일입니다. 진정으로 올바른 다중 스레드 프로그램의 경우 프로그래머의 개입이 거의 확실하게 요구 사항입니다. 한편, 성능 특성과 실행에 대해서는 아직 깊이 있게 설명되지 않았다. 수년에 걸쳐 다중 스레드 프로그램을 많이 작성하면서 원자가 어떤 목적에도 적합하지 않기 때문에 nonatomic
이 질문에 대한 원자 및 비원자 속성의 세부 사항에 대해 논의하는 동안 프로파일링을 수행한 결과 흥미로운 결과가 나타났습니다.
실행
확인. 가장 먼저 정리하고 싶은 것은 잠금 구현이 구현에서 정의되고 추상화된다는 것입니다. Louis는 @synchronized(self)
를 사용합니다 -- 나는 이것을 혼동의 일반적인 원인으로 보았습니다. 구현은 실제로 @synchronized(self)
사용하지 않습니다. 그것은 개체 수준 스핀 잠금을 사용합니다. Louis의 일러스트레이션은 우리 모두에게 익숙한 구조를 사용하는 높은 수준의 일러스트레이션에 적합하지만 @synchronized(self)
사용하지 않는다는 것을 아는 것이 중요합니다.
또 다른 차이점은 원자 속성이 getter 내에서 객체를 유지/해제 주기를 유지한다는 것입니다.
성능
흥미로운 부분이 있습니다. 경쟁이 없는 (예: 단일 스레드) 경우에 원자 속성 액세스를 사용하는 성능은 어떤 경우에는 정말 매우 빠를 수 있습니다. 이상적이지 않은 경우, 원자적 접근을 사용하는 것은 nonatomic
의 오버헤드의 20배 이상의 비용이 들 수 있습니다. 7개의 스레드를 사용하는 Contested 케이스는 3바이트 구조체(2.2GHz Core i7 Quad Core, x86_64)의 경우 44배 느렸습니다. 3바이트 구조체는 매우 느린 속성의 예입니다.
흥미로운 참고 사항: 3바이트 구조체의 사용자 정의 접근자는 합성된 원자 접근자보다 52배 빠릅니다. 또는 합성된 비원자 접근자의 84% 속도.
다툼이 있는 경우의 개체도 50배를 초과할 수 있습니다.
최적화의 수와 구현의 변형으로 인해 이러한 컨텍스트에서 실제 영향을 측정하는 것은 매우 어렵습니다. "프로필을 보고 문제가 되지 않는 한 믿으세요"와 같은 말을 종종 들을 수 있습니다. 추상화 수준으로 인해 실제 영향을 측정하는 것은 실제로 매우 어렵습니다. 프로필에서 실제 비용을 수집하는 것은 시간이 많이 소요될 수 있으며 추상화로 인해 매우 정확하지 않습니다. 또한 ARC 대 MRC는 큰 차이를 만들 수 있습니다.
따라서 속성 액세스 구현에 초점을 맞추지 않고 objc_msgSend
와 같은 일반적인 용의자를 포함하고 경쟁이 없는 경우(초 단위 값)에서 NSString
getter에 대한 많은 호출에 대한 실제 고수준 결과를 조사합니다.
아마 짐작하셨겠지만 참조 카운트 활동/순환은 원자 및 ARC에서 중요한 기여자입니다. 또한 다툼이 있는 경우에는 더 큰 차이를 볼 수 있습니다.
성능에 신경을 많이 쓰긴 하지만 그래도 저는 시맨틱 퍼스트라고 합니다! . 한편, 성능은 많은 프로젝트에서 낮은 우선 순위입니다. 그러나 사용하는 기술의 실행 세부 정보와 비용을 아는 것은 확실히 문제가 되지 않습니다. 귀하의 필요, 목적 및 능력에 적합한 기술을 사용해야 합니다. 이렇게 하면 비교하는 데 몇 시간이 절약되고 프로그램을 설계할 때 정보에 입각한 결정을 내리는 데 도움이 됩니다.
원자 = 스레드 안전성
비원자 = 스레드 안전성 없음
인스턴스 변수는 런타임 환경에 의한 해당 스레드 실행의 스케줄링 또는 인터리빙에 관계없이 그리고 호출 코드 부분에서 추가 동기화 또는 기타 조정 없이 여러 스레드에서 액세스할 때 올바르게 동작하는 경우 스레드로부터 안전합니다.
스레드가 인스턴스의 값을 변경하면 변경된 값은 모든 스레드에서 사용할 수 있으며 한 번에 하나의 스레드만 값을 변경할 수 있습니다.
atomic
를 사용하는 곳:인스턴스 변수가 다중 스레드 환경에서 액세스되는 경우.
atomic
의미: 아니 빨리으로 nonatomic
때문에 nonatomic
런타임에서 해당에 어떤 감시 작업을 필요로하지 않습니다.
nonatomic
사용처:인스턴스 변수가 여러 스레드에 의해 변경되지 않을 경우 사용할 수 있습니다. 성능을 향상시킵니다.
Stack Overflow에 게시된 많은 기사를 읽고 가변 속성 속성을 확인하는 데모 애플리케이션을 만든 후 모든 속성 정보를 함께 넣기로 결정했습니다.
atomic
// 기본값nonatomic
strong = retain
// 기본값weak = unsafe_unretained
retain
assign
// 기본값unsafe_unretained
copy
readonly
readwrite
// 기본값iOS의 변수 속성 속성 또는 수정자 기사에서 위에서 언급한 모든 속성을 찾을 수 있으며, 이는 확실히 도움이 될 것입니다.
atomic
atomic
은 하나의 스레드만 변수에 액세스함을 의미합니다(정적 유형).atomic
은 스레드로부터 안전합니다.atomic
는 기본 동작입니다예시:
@property (retain) NSString *name; @synthesize name;
nonatomic
nonatomic
은 다중 스레드가 변수에 액세스하는 것을 의미합니다(동적 유형).nonatomic
은 스레드로부터 안전하지 않습니다.nonatomic
은 기본 동작이 아닙니다. 속성 속성에 nonatomic
키워드를 추가해야 합니다.예시:
@property (nonatomic, retain) NSString *name; @synthesize name;
여기 에서 원자 및 비원자 속성에 대한 설명이 꽤 잘 되어 있음을 발견했습니다. 다음은 동일한 내용의 관련 텍스트입니다.
'원자'는 분해할 수 없다는 의미입니다. OS/프로그래밍 용어에서 원자적 기능 호출은 중단될 수 없는 것입니다. 전체 기능이 실행되어야 하며 완료될 때까지 OS의 일반적인 컨텍스트 전환에 의해 CPU에서 스왑 아웃되지 않아야 합니다. 모르는 경우를 대비하여: CPU는 한 번에 한 가지만 수행할 수 있으므로 OS는 CPU에 대한 액세스를 실행 중인 모든 프로세스에 대해 약간의 시간 분할로 순환하여 멀티태스킹 의 환상을 줍니다. CPU 스케줄러는 실행 중 언제라도 프로세스를 중단할 수 있습니다. 따라서 두 프로세스가 동시에 변수 업데이트를 시도할 수 있는 공유 카운터 변수 업데이트와 같은 작업의 경우 '원자적으로' 실행되어야 합니다. CPU.
따라서 이 경우 원자성은 속성 판독기 메서드가 중단될 수 없음을 의미한다고 추측합니다. 즉, 실제로 메서드에서 읽는 변수가 다른 스레드/호출/함수가 가져오기 때문에 중간에 값을 변경할 수 없음을 의미합니다. CPU로 바꿨습니다.
atomic
변수는 중단될 수 없기 때문에 어떤 시점에서든 해당 변수에 포함된 값은 손상되지 않은 것으로 (스레드 잠금) 보장되지만 이 스레드 잠금을 보장하면 액세스 속도가 느려집니다. non-atomic
변수는 그러한 보장을 하지 않지만 더 빠른 액세스의 사치를 제공합니다. 요약하자면, 여러 스레드에서 동시에 변수에 액세스하지 않고 속도를 높일 수 있다는 것을 알고 있는 경우 non-atomic
Atomic은 속성에 대한 액세스가 원자적 방식으로 수행됨을 보장합니다. 예를 들어 항상 완전히 초기화된 객체를 반환하므로 한 스레드의 속성 가져오기/집합이 완료되어야 다른 스레드가 액세스할 수 있습니다.
한 번에 두 개의 스레드에서 다음 함수가 발생하는 것을 상상하면 결과가 좋지 않은 이유를 알 수 있습니다.
-(void) setName:(NSString*)string { if (name) { [name release]; // what happens if the second thread jumps in now !? // name may be deleted, but our 'name' variable is still set! name = nil; } ... }
장점 : 매번 완전히 초기화된 객체를 반환하므로 멀티 스레딩의 경우 가장 좋은 선택입니다.
단점 : 성능 저하, 실행 속도가 약간 느려짐
Atomic과 달리 매번 완전히 초기화된 객체 반환을 보장하지는 않습니다.
장점 : 매우 빠른 실행.
단점 : 멀티 쓰레드의 경우 가비지 값이 나올 확률.
가장 쉬운 대답이 먼저입니다. 두 번째 두 예제 사이에는 차이가 없습니다. 기본적으로 속성 접근자는 원자적입니다.
가비지 수집되지 않은 환경(즉, 유지/해제/자동 해제를 사용할 때)의 원자 접근자는 잠금을 사용하여 다른 스레드가 값의 올바른 설정/가져오기를 방해하지 않도록 합니다.
Apple의 Objective-C 2.0 문서에서 " 성능 및 스레딩 " 섹션을 참조하여 다중 스레드 앱을 만들 때 더 많은 정보와 기타 고려 사항을 확인하십시오.
Atomic은 하나의 스레드만 변수(정적 유형)에 액세스한다는 것을 의미합니다. Atomic은 스레드로부터 안전하지만 느립니다.
Nonatomic은 여러 스레드가 변수에 액세스하는 것을 의미합니다(동적 유형). Nonatomic은 스레드로부터 안전하지 않지만 빠릅니다.
Atomic은 스레드로부터 안전 하며, 느리고 동일한 영역에서 액세스를 시도하는 스레드 수에 관계없이 잠긴 값만 제공되도록 보장합니다(보장되지 않음). atomic을 사용할 때 이 함수 내부에 작성된 코드는 한 번에 하나의 스레드만 실행할 수 있는 임계 영역의 일부가 됩니다.
스레드 안전성만 보장합니다. 그것을 보장하지 않습니다. 내 말은 당신이 당신의 차를 위해 전문 운전사를 고용한다는 것입니다. 그래도 차가 사고를 당하지 않을 것이라는 보장은 없습니다. 그러나 가능성은 미미합니다.
Atomic - 분해할 수 없으므로 결과가 예상됩니다. 비원자 - 다른 스레드가 메모리 영역에 액세스할 때 수정할 수 있으므로 결과가 예기치 않습니다.
코드 토크:
원자는 속성의 getter 및 setter를 스레드로부터 안전하게 만듭니다. 예를 들어 다음과 같이 작성했다면
self.myProperty = value;
스레드로부터 안전합니다.
[myArray addObject:@"Abc"]
스레드로부터 안전하지 않습니다.
원자(기본값)
Atomic이 기본값입니다. 아무 것도 입력하지 않으면 속성이 atomic입니다. 원자성 속성은 읽기를 시도하면 유효한 값을 반환하도록 보장됩니다. 그 값이 무엇인지 보장하지는 않지만 정크 메모리뿐만 아니라 좋은 데이터를 얻을 수 있습니다. 이를 통해 수행할 수 있는 작업은 단일 변수를 가리키는 여러 스레드 또는 여러 프로세스가 있는 경우 한 스레드는 읽고 다른 스레드는 쓸 수 있다는 것입니다. 동시에 적중하면 리더 스레드는 변경 전 또는 변경 후의 두 값 중 하나를 얻도록 보장됩니다. 원자가 제공하지 않는 것은 이러한 값 중 어떤 것을 얻을 수 있는지에 대한 일종의 보증입니다. Atomic은 일반적으로 스레드로부터 안전한 것과 혼동되며 이는 옳지 않습니다. 다른 방법으로 스레드 안전성을 보장해야 합니다. 그러나 atomic은 읽기를 시도하면 어떤 종류의 가치를 되돌려 받을 수 있음을 보장합니다.
비원자
반면에, 당신이 추측할 수 있듯이, 비원자적은 단지 "그 원자적인 일을 하지 말라"는 의미입니다. 당신이 잃는 것은 당신이 항상 무언가를 되찾는다는 보장입니다. 쓰기 도중에 읽으려고 하면 가비지 데이터를 다시 얻을 수 있습니다. 그러나 반면에, 당신은 조금 더 빨리 갑니다. 원자 속성은 값을 되돌리도록 보장하기 위해 약간의 마법을 수행해야 하기 때문에 약간 느립니다. 많이 액세스하는 속성인 경우 속도 패널티가 발생하지 않는지 확인하기 위해 nonatomic으로 드롭다운할 수 있습니다.
자세한 내용은 https://realm.io/news/tmi-objective-c-property-attributes/를 참조하세요.
"원자"라는 키워드가 없습니다.
@property(atomic, retain) UITextField *userName;
우리는 위와 같이 사용할 수 있습니다
@property(retain) UITextField *userName;
@property(atomic,retain)NSString *myString 을 사용하면 스택 오버플로 질문이 발생합니다.를 참조하세요.
기본값 은 atomic
. 즉, 속성을 사용할 때마다 성능이 저하되지만 스레드로부터 안전합니다. Objective-C가 하는 일은 잠금을 설정하는 것이므로 setter/getter가 실행되는 한 실제 스레드만 변수에 액세스할 수 있습니다.
ivar _internal이 있는 속성의 MRC 예제:
[_internal lock]; //lock id result = [[value retain] autorelease]; [_internal unlock]; return result;
따라서 이 마지막 두 가지는 동일합니다.
@property(atomic, retain) UITextField *userName; @property(retain) UITextField *userName; // defaults to atomic
반면에 nonatomic
은 코드에 아무것도 추가하지 않습니다. 따라서 보안 메커니즘을 직접 코딩하는 경우에만 스레드로부터 안전합니다.
@property(nonatomic, retain) UITextField *userName;
키워드는 첫 번째 속성 속성으로 작성할 필요가 전혀 없습니다.
이것은 속성이 전체적으로 스레드로부터 안전하다는 것을 의미하지 않는다는 것을 잊지 마십시오. setter/getter의 메서드 호출만 있습니다. 그러나 setter를 사용하고 그 후에 getter를 2개의 다른 스레드로 동시에 사용하는 경우에도 손상될 수 있습니다!
선언 방법:
원자는 기본이므로,
@property (retain) NSString *name;
AND 구현 파일에서
self.name = @"sourov";
세 가지 속성과 관련된 작업이 다음과 같다고 가정합니다.
@property (retain) NSString *name; @property (retain) NSString *A; @property (retain) NSString *B; self.name = @"sourov";
모든 속성은 병렬로 작동합니다(비동기식처럼).
스레드 A 에서 "이름"을 호출하면
그리고
동시에 전화를 걸면
[self setName:@"Datta"]
스레드 B에서 ,
이제 *name 속성이 원자가 아닌 경우
그래서 non-atomic을 thread unsafe라고 하지만 병렬 실행으로 인해 성능이 빠릅니다.
이제 *name 속성이 원자성인 경우
이것이 원자가 스레드 세이프라고 불리는 이유이며 읽기-쓰기 세이프라고 불리는 이유입니다.
이러한 상황 작업은 순차적으로 수행됩니다. 그리고 성능이 느림
- Nonatomic은 다중 스레드가 변수(동적 유형)에 액세스하는 것을 의미합니다.
- Nonatomic은 스레드가 안전하지 않습니다.
- 하지만 성능이 빠름
- Nonatomic은 기본 동작이 아니므로 속성 속성에 nonatomic 키워드를 추가해야 합니다.
For In Swift Swift 속성이 ObjC 의미에서 원자가 아님을 확인합니다. 한 가지 이유는 속성별 원자성이 요구 사항에 충분한지 여부를 생각하기 때문입니다.
참조: https://forums.developer.apple.com/thread/25642
자세한 정보는 http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html 웹사이트를 방문하십시오.
다중 스레드 코드에서 속성을 사용하는 경우 비원자 속성과 원자 속성 간의 차이를 볼 수 있습니다. Nonatomic은 atomic보다 빠르며 atomic은 nonatomic이 아닌 스레드로부터 안전합니다.
Vijayendra Tripathi는 이미 다중 스레드 환경에 대한 예를 제공했습니다.
시작하기 전에: 새 기록기가 발생하려면 메모리의 모든 개체가 메모리에서 할당 해제되어야 한다는 것을 알아야 합니다. 단순히 종이에 하는 것처럼 무언가 위에 쓸 수는 없습니다. 먼저 (할당 해제)을 삭제해야한다을 그리고 당신은 그것에 쓸 수 있습니다. 지우기가 완료(또는 반은 완료)되고 아무 것도 기록되지 않은(또는 반은 기록된) 순간에 읽으려고 하면 매우 문제가 될 수 있습니다! 원자 및 비 원자는 이 문제를 다른 방식으로 처리하는 데 도움이 됩니다.
먼저 이 질문을 읽은 다음 Bbum의 답변 을 읽으십시오. 또한 내 요약을 읽으십시오.
atomic
는 항상 보장합니다
Retain count는 Objective-C에서 메모리를 관리하는 방식입니다. 개체를 생성할 때 개체의 유지 횟수는 1입니다. 개체에 유지 메시지를 보내면 개체의 유지 횟수가 1씩 증가합니다. 개체에 릴리스 메시지를 보내면 개체의 유지 횟수가 1만큼 감소합니다. 객체에 autorelease 메시지를 보내면 그 보유 횟수는 미래의 어떤 단계에서 1만큼 감소합니다. 객체의 보유 횟수가 0으로 줄어들면 할당이 해제됩니다.
뭐?! 멀티스레딩과 스레드 안전성은 다른가요?
예. 멀티스레딩은 여러 스레드가 동시에 공유 데이터 조각을 읽을 수 있으며 충돌이 일어나지는 않지만 자동 해제되지 않은 값에서 읽지 않는다는 것을 보장하지는 않습니다. 스레드 안전성을 사용하면 읽은 내용이 자동으로 해제되지 않습니다. 기본적으로 모든 것을 원자성으로 만들지 않는 이유는 성능 비용이 있고 대부분의 경우 스레드 안전성이 실제로 필요하지 않기 때문입니다. 우리 코드의 몇몇 부분에 그것을 필요로 하고 그 몇몇 부분에 대해서는 잠금, 뮤텍스 또는 동기화를 사용하여 스레드로부터 안전한 방식으로 코드를 작성해야 합니다.
nonatomic
전반적으로 두 가지 측면에서 다릅니다.
자동 릴리스 풀의 유무로 인해 충돌이 발생하거나 발생하지 않습니다.
'아직 쓰기가 완료되지 않았거나 값이 비어 있는' 중간에 바로 읽기를 허용하거나 값이 완전히 쓰여졌을 때만 읽기를 허용하지 않고 허용합니다.
원자성 원자(기본값)
Atomic이 기본값입니다. 아무 것도 입력하지 않으면 속성이 atomic입니다. 원자성 속성은 읽기를 시도하면 유효한 값을 반환하도록 보장됩니다. 그 값이 무엇인지 보장하지는 않지만 정크 메모리뿐만 아니라 좋은 데이터를 얻을 수 있습니다. 이를 통해 수행할 수 있는 작업은 단일 변수를 가리키는 여러 스레드 또는 여러 프로세스가 있는 경우 한 스레드는 읽고 다른 스레드는 쓸 수 있다는 것입니다. 동시에 적중하면 리더 스레드는 변경 전 또는 변경 후의 두 값 중 하나를 얻도록 보장됩니다. 원자가 제공하지 않는 것은 이러한 값 중 어떤 것을 얻을 수 있는지에 대한 일종의 보증입니다. Atomic은 일반적으로 스레드로부터 안전한 것과 혼동되며 이는 옳지 않습니다. 다른 방법으로 스레드 안전성을 보장해야 합니다. 그러나 atomic은 읽기를 시도하면 어떤 종류의 가치를 되돌려 받을 수 있음을 보장합니다.
비원자
반면에, 당신이 추측할 수 있듯이, 비원자적은 단지 "그 원자적인 일을 하지 말라"는 의미입니다. 당신이 잃는 것은 당신이 항상 무언가를 되찾는다는 보장입니다. 쓰기 도중에 읽으려고 하면 가비지 데이터를 다시 얻을 수 있습니다. 그러나 반면에, 당신은 조금 더 빨리 갑니다. 원자 속성은 값을 되돌리도록 보장하기 위해 약간의 마법을 수행해야 하기 때문에 약간 느립니다. 많이 액세스하는 속성인 경우 속도 패널티가 발생하지 않는지 확인하기 위해 nonatomic으로 드롭다운할 수 있습니다. 접속하다
예의 https://academy.realm.io/posts/tmi-objective-c-property-attributes/
원자성 속성 속성(원자 및 비원자)은 해당하는 Swift 속성 선언에 반영되지 않지만, Swift에서 가져온 속성에 액세스할 때 Objective-C 구현의 원자성 보장은 여전히 유지됩니다.
따라서 - Objective-C에서 원자성 속성을 정의하면 Swift에서 사용할 때 원자성으로 유지됩니다.
예의 https://medium.com/@YogevSitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c
원자 속성은 얼마나 많은 스레드가 getter 및 setter를 수행하는지에 관계없이 완전히 초기화된 값을 유지하도록 합니다.
nonatomic 속성은 합성된 접근자가 값을 직접 설정하거나 반환하도록 지정하며, 동일한 값이 다른 스레드에서 동시에 액세스되는 경우 어떤 일이 발생하는지 보장하지 않습니다.
원자성은 한 번에 하나의 스레드만 변수에 액세스할 수 있음을 의미합니다(정적 유형). Atomic은 스레드로부터 안전하지만 느립니다.
Nonatomic은 여러 스레드가 동시에 변수에 액세스할 수 있음을 의미합니다(동적 유형). Nonatomic은 스레드로부터 안전하지 않지만 빠릅니다.
진실은 스핀 잠금을 사용하여 원자 속성을 구현한다는 것입니다. 아래와 같은 코드:
static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) { id oldValue; id *slot = (id*) ((char*)self + offset); if (copy) { newValue = [newValue copyWithZone:NULL]; } else if (mutableCopy) { newValue = [newValue mutableCopyWithZone:NULL]; } else { if (*slot == newValue) return; newValue = objc_retain(newValue); } if (!atomic) { oldValue = *slot; *slot = newValue; } else { spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)]; _spin_lock(slotlock); oldValue = *slot; *slot = newValue; _spin_unlock(slotlock); } objc_release(oldValue); }
한 줄로:
Atomic
은 스레드로부터 안전합니다. Nonatomic
은 스레드로부터 안전하지 않습니다.
원자성을 사용하는 경우 스레드가 안전하고 읽기 전용임을 의미합니다. 비원자성을 사용하는 경우 다중 스레드가 변수에 액세스하고 스레드가 안전하지 않지만 빠르게 실행되고 읽기 및 쓰기 작업이 수행됨을 의미합니다. 이것은 동적 유형입니다.
Atomic: NSLOCK을 사용하여 스레드를 잠궈 스레드 안전성을 보장합니다.
비 원자성: 스레드 잠금 메커니즘이 없기 때문에 스레드 안전성을 보장하지 않습니다.
전체 혼란을 단순화하기 위해 뮤텍스 잠금을 이해합시다.
Mutex 잠금은 이름에 따라 개체의 가변성을 잠급니다. 따라서 클래스가 개체에 액세스하면 다른 클래스는 동일한 개체에 액세스할 수 없습니다.
iOS에서 @sychronise
는 뮤텍스 잠금도 제공합니다. 이제 FIFO 모드에서 작동하며 흐름이 동일한 인스턴스를 공유하는 두 클래스의 영향을 받지 않도록 합니다. 그러나 작업이 기본 스레드에 있는 경우 UI를 유지하고 성능을 저하시킬 수 있으므로 원자 속성을 사용하여 개체에 액세스하지 마십시오.
원자 속성 :- 원자 속성이 할당된 변수는 단 하나의 스레드 액세스 권한을 가지며 스레드로부터 안전하고 성능 관점에서 우수하다는 것을 의미하며 기본 동작을 갖습니다.
비 원자 속성 :- 다중 스레드 액세스가 있고 스레드로부터 안전하지 않고 성능 관점에서 느릴 것임을 의미하는 원자 속성이 할당된 변수는 기본 동작을 가지며 두 개의 다른 스레드가 동시에 변수에 액세스하려고 할 때 의외의 결과를 줄 것입니다.
출처 : http:www.stackoverflow.com/questions/588866/whats-the-difference-between-the-atomic-and-nonatomic-attributes
PostgreSQL 명령줄 유틸리티를 종료하는 방법: psql (0) | 2021.12.26 |
---|---|
값으로 배열 복사 (0) | 2021.12.26 |
Git 커밋의 변경 사항을 어떻게 볼 수 있습니까? (0) | 2021.12.26 |
Bash에 변수가 설정되어 있는지 확인하는 방법은 무엇입니까? (0) | 2021.12.26 |
Android에서 화면 크기를 픽셀로 얻는 방법 (0) | 2021.12.26 |