etc./StackOverFlow

원자 속성과 비 원자 속성의 차이점은 무엇입니까?

청렴결백한 만능 재주꾼 2021. 12. 26. 04:07
반응형

질문자 :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 대한 액세스를 제외할 수 있는 다른 종류의 동기화 및/또는 제외입니다.


bbum

이것은 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으로 떨어지는 경우 잠재적 경쟁 조건입니다.

속성이 스칼라 값인지 객체인지, 그리고 유지, 복사, 읽기 전용, 비원자 등이 상호 작용하는 방식에 따라 실제로 이러한 것들이 작동하는 방식의 다양한 변형이 있습니다. 일반적으로 속성 합성기는 모든 조합에 대해 "올바른 일"을 수행하는 방법만 알고 있습니다.


Louis Gerbarg

원자

  • 기본 동작입니다
  • 다른 프로세스가 변수에 액세스하기 전에 현재 프로세스가 CPU에 의해 완료되었는지 확인합니다.
  • 프로세스가 완전히 완료되도록 보장하므로 빠르지 않습니다.

비원자

  • 기본 동작이 아닙니다.
  • 더 빠름(합성 코드의 경우, 즉 @property 및 @synthesize를 사용하여 생성된 변수의 경우)
  • 스레드로부터 안전하지 않음
  • 두 개의 다른 프로세스가 동시에 동일한 변수에 액세스할 때 예기치 않은 동작이 발생할 수 있습니다.

raw3d

차이점을 이해하는 가장 좋은 방법은 다음 예를 사용하는 것입니다.

이 "이름"이라는 원자 문자열 속성이며, 당신이 호출하면 가정 [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는 여전히 병렬로 실행할 수 있습니다.


Vijayendra

구문과 의미는 이 질문에 대한 다른 훌륭한 답변에 의해 이미 잘 정의되어 있습니다. 실행성능 이 잘 나와있지 않아 답변을 추가하겠습니다.

이 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에 대한 많은 호출에 대한 실제 고수준 결과를 조사합니다.

  • MRC | 비원자 | 수동으로 구현된 getter: 2
  • MRC | 비원자 | 합성 게터: 7
  • MRC | 원자 | 합성 게터: 47
  • 아크 | 비원자 | 합성된 getter: 38(참고: ARC는 여기에 참조 카운트 순환을 추가함)
  • 아크 | 원자 | 합성 게터: 47

아마 짐작하셨겠지만 참조 카운트 활동/순환은 원자 및 ARC에서 중요한 기여자입니다. 또한 다툼이 있는 경우에는 더 큰 차이를 볼 수 있습니다.

성능에 신경을 많이 쓰긴 하지만 그래도 저는 시맨틱 퍼스트라고 합니다! . 한편, 성능은 많은 프로젝트에서 낮은 우선 순위입니다. 그러나 사용하는 기술의 실행 세부 정보와 비용을 아는 것은 확실히 문제가 되지 않습니다. 귀하의 필요, 목적 및 능력에 적합한 기술을 사용해야 합니다. 이렇게 하면 비교하는 데 몇 시간이 절약되고 프로그램을 설계할 때 정보에 입각한 결정을 내리는 데 도움이 됩니다.


justin

원자 = 스레드 안전성

비원자 = 스레드 안전성 없음

스레드 안전성:

인스턴스 변수는 런타임 환경에 의한 해당 스레드 실행의 스케줄링 또는 인터리빙에 관계없이 그리고 호출 코드 부분에서 추가 동기화 또는 기타 조정 없이 여러 스레드에서 액세스할 때 올바르게 동작하는 경우 스레드로부터 안전합니다.

우리의 맥락에서:

스레드가 인스턴스의 값을 변경하면 변경된 값은 모든 스레드에서 사용할 수 있으며 한 번에 하나의 스레드만 값을 변경할 수 있습니다.

atomic 를 사용하는 곳:

인스턴스 변수가 다중 스레드 환경에서 액세스되는 경우.

atomic 의미:

아니 빨리으로 nonatomic 때문에 nonatomic 런타임에서 해당에 어떤 감시 작업을 필요로하지 않습니다.

nonatomic 사용처:

인스턴스 변수가 여러 스레드에 의해 변경되지 않을 경우 사용할 수 있습니다. 성능을 향상시킵니다.


Durai Amuthan.H

Stack Overflow에 게시된 많은 기사를 읽고 가변 속성 속성을 확인하는 데모 애플리케이션을 만든 후 모든 속성 정보를 함께 넣기로 결정했습니다.

  1. atomic // 기본값
  2. nonatomic
  3. strong = retain // 기본값
  4. weak = unsafe_unretained
  5. retain
  6. assign // 기본값
  7. unsafe_unretained
  8. copy
  9. readonly
  10. readwrite // 기본값

iOS의 변수 속성 속성 또는 수정자 기사에서 위에서 언급한 모든 속성을 찾을 수 있으며, 이는 확실히 도움이 될 것입니다.

  1. atomic

    • atomic 은 하나의 스레드만 변수에 액세스함을 의미합니다(정적 유형).
    • atomic 은 스레드로부터 안전합니다.
    • 하지만 성능이 느리다.
    • atomic 는 기본 동작입니다
    • 가비지 수집되지 않은 환경(즉, 유지/해제/자동 해제를 사용할 때)의 원자 접근자는 잠금을 사용하여 다른 스레드가 값의 올바른 설정/가져오기를 방해하지 않도록 합니다.
    • 실제로 키워드가 아닙니다.

    예시:

     @property (retain) NSString *name; @synthesize name;
  2. nonatomic

    • nonatomic 은 다중 스레드가 변수에 액세스하는 것을 의미합니다(동적 유형).
    • nonatomic 은 스레드로부터 안전하지 않습니다.
    • 하지만 성능이 빠르다.
    • nonatomic 은 기본 동작이 아닙니다. 속성 속성에 nonatomic 키워드를 추가해야 합니다.
    • 두 개의 서로 다른 프로세스(스레드)가 동일한 변수에 동시에 액세스하면 예기치 않은 동작이 발생할 수 있습니다.

    예시:

     @property (nonatomic, retain) NSString *name; @synthesize name;

swiftBoy

여기 에서 원자 및 비원자 속성에 대한 설명이 꽤 잘 되어 있음을 발견했습니다. 다음은 동일한 내용의 관련 텍스트입니다.

'원자'는 분해할 수 없다는 의미입니다. OS/프로그래밍 용어에서 원자적 기능 호출은 중단될 수 없는 것입니다. 전체 기능이 실행되어야 하며 완료될 때까지 OS의 일반적인 컨텍스트 전환에 의해 CPU에서 스왑 아웃되지 않아야 합니다. 모르는 경우를 대비하여: CPU는 한 번에 한 가지만 수행할 수 있으므로 OS는 CPU에 대한 액세스를 실행 중인 모든 프로세스에 대해 약간의 시간 분할로 순환하여 멀티태스킹 의 환상을 줍니다. CPU 스케줄러는 실행 중 언제라도 프로세스를 중단할 수 있습니다. 따라서 두 프로세스가 동시에 변수 업데이트를 시도할 수 있는 공유 카운터 변수 업데이트와 같은 작업의 경우 '원자적으로' 실행되어야 합니다. CPU.

따라서 이 경우 원자성은 속성 판독기 메서드가 중단될 수 없음을 의미한다고 추측합니다. 즉, 실제로 메서드에서 읽는 변수가 다른 스레드/호출/함수가 가져오기 때문에 중간에 값을 변경할 수 없음을 의미합니다. CPU로 바꿨습니다.

atomic 변수는 중단될 수 없기 때문에 어떤 시점에서든 해당 변수에 포함된 값은 손상되지 않은 것으로 (스레드 잠금) 보장되지만 이 스레드 잠금을 보장하면 액세스 속도가 느려집니다. non-atomic 변수는 그러한 보장을 하지 않지만 더 빠른 액세스의 사치를 제공합니다. 요약하자면, 여러 스레드에서 동시에 변수에 액세스하지 않고 속도를 높일 수 있다는 것을 알고 있는 경우 non-atomic


tipycalFlow

원자:

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과 달리 매번 완전히 초기화된 객체 반환을 보장하지는 않습니다.

장점 : 매우 빠른 실행.

단점 : 멀티 쓰레드의 경우 가비지 값이 나올 확률.


Andrew Grant

가장 쉬운 대답이 먼저입니다. 두 번째 두 예제 사이에는 차이가 없습니다. 기본적으로 속성 접근자는 원자적입니다.

가비지 수집되지 않은 환경(즉, 유지/해제/자동 해제를 사용할 때)의 원자 접근자는 잠금을 사용하여 다른 스레드가 값의 올바른 설정/가져오기를 방해하지 않도록 합니다.

Apple의 Objective-C 2.0 문서에서 " 성능 및 스레딩 " 섹션을 참조하여 다중 스레드 앱을 만들 때 더 많은 정보와 기타 고려 사항을 확인하십시오.


Jay O'Conor

Atomic은 하나의 스레드만 변수(정적 유형)에 액세스한다는 것을 의미합니다. Atomic은 스레드로부터 안전하지만 느립니다.

Nonatomic은 여러 스레드가 변수에 액세스하는 것을 의미합니다(동적 유형). Nonatomic은 스레드로부터 안전하지 않지만 빠릅니다.


IOS Rocks

Atomic은 스레드로부터 안전 하며, 느리고 동일한 영역에서 액세스를 시도하는 스레드 수에 관계없이 잠긴 값만 제공되도록 보장합니다(보장되지 않음). atomic을 사용할 때 이 함수 내부에 작성된 코드는 한 번에 하나의 스레드만 실행할 수 있는 임계 영역의 일부가 됩니다.

스레드 안전성만 보장합니다. 그것을 보장하지 않습니다. 내 말은 당신이 당신의 차를 위해 전문 운전사를 고용한다는 것입니다. 그래도 차가 사고를 당하지 않을 것이라는 보장은 없습니다. 그러나 가능성은 미미합니다.

Atomic - 분해할 수 없으므로 결과가 예상됩니다. 비원자 - 다른 스레드가 메모리 영역에 액세스할 때 수정할 수 있으므로 결과가 예기치 않습니다.

코드 토크:

원자는 속성의 getter 및 setter를 스레드로부터 안전하게 만듭니다. 예를 들어 다음과 같이 작성했다면

 self.myProperty = value;

스레드로부터 안전합니다.

 [myArray addObject:@"Abc"]

스레드로부터 안전하지 않습니다.


user3693546

원자(기본값)

Atomic이 기본값입니다. 아무 것도 입력하지 않으면 속성이 atomic입니다. 원자성 속성은 읽기를 시도하면 유효한 값을 반환하도록 보장됩니다. 그 값이 무엇인지 보장하지는 않지만 정크 메모리뿐만 아니라 좋은 데이터를 얻을 수 있습니다. 이를 통해 수행할 수 있는 작업은 단일 변수를 가리키는 여러 스레드 또는 여러 프로세스가 있는 경우 한 스레드는 읽고 다른 스레드는 쓸 수 있다는 것입니다. 동시에 적중하면 리더 스레드는 변경 전 또는 변경 후의 두 값 중 하나를 얻도록 보장됩니다. 원자가 제공하지 않는 것은 이러한 값 중 어떤 것을 얻을 수 있는지에 대한 일종의 보증입니다. Atomic은 일반적으로 스레드로부터 안전한 것과 혼동되며 이는 옳지 않습니다. 다른 방법으로 스레드 안전성을 보장해야 합니다. 그러나 atomic은 읽기를 시도하면 어떤 종류의 가치를 되돌려 받을 수 있음을 보장합니다.

비원자

반면에, 당신이 추측할 수 있듯이, 비원자적은 단지 "그 원자적인 일을 하지 말라"는 의미입니다. 당신이 잃는 것은 당신이 항상 무언가를 되찾는다는 보장입니다. 쓰기 도중에 읽으려고 하면 가비지 데이터를 다시 얻을 수 있습니다. 그러나 반면에, 당신은 조금 더 빨리 갑니다. 원자 속성은 값을 되돌리도록 보장하기 위해 약간의 마법을 수행해야 하기 때문에 약간 느립니다. 많이 액세스하는 속성인 경우 속도 패널티가 발생하지 않는지 확인하기 위해 nonatomic으로 드롭다운할 수 있습니다.

자세한 내용은 https://realm.io/news/tmi-objective-c-property-attributes/를 참조하세요.


Proton

"원자"라는 키워드가 없습니다.

 @property(atomic, retain) UITextField *userName;

우리는 위와 같이 사용할 수 있습니다

 @property(retain) UITextField *userName;

@property(atomic,retain)NSString *myString 을 사용하면 스택 오버플로 질문이 발생합니다.를 참조하세요.


Community Wiki

기본값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개의 다른 스레드로 동시에 사용하는 경우에도 손상될 수 있습니다!


Binarian

  • -Atomic은 하나의 스레드만 변수(정적 유형)에 액세스하는 것을 의미합니다.
  • -Atomic은 스레드로부터 안전합니다.
  • - 그러나 성능이 느림

선언 방법:

원자는 기본이므로,

 @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 속성이 원자가 아닌 경우

  • A에 대해 "Datta" 값을 반환합니다.
  • B에 대해 "Datta" 값을 반환합니다.

그래서 non-atomic을 thread unsafe라고 하지만 병렬 실행으로 인해 성능이 빠릅니다.

이제 *name 속성이 원자성인 경우

  • 그것은 A에 대한 가치 "Sourov"를 보장할 것입니다.
  • 그런 다음 B에 대한 값 "Datta"를 반환합니다.

이것이 원자가 스레드 세이프라고 불리는 이유이며 읽기-쓰기 세이프라고 불리는 이유입니다.

이러한 상황 작업은 순차적으로 수행됩니다. 그리고 성능이 느림

- 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 웹사이트를 방문하십시오.


Shourob Datta

다중 스레드 코드에서 속성을 사용하는 경우 비원자 속성과 원자 속성 간의 차이를 볼 수 있습니다. Nonatomic은 atomic보다 빠르며 atomic은 nonatomic이 아닌 스레드로부터 안전합니다.

Vijayendra Tripathi는 이미 다중 스레드 환경에 대한 예를 제공했습니다.


Ankul Gaur

시작하기 전에: 새 기록기가 발생하려면 메모리의 모든 개체가 메모리에서 할당 해제되어야 한다는 것을 알아야 합니다. 단순히 종이에 하는 것처럼 무언가 위에 쓸 수는 없습니다. 먼저 (할당 해제)을 삭제해야한다을 그리고 당신은 그것에 쓸 수 있습니다. 지우기가 완료(또는 반은 완료)되고 아무 것도 기록되지 않은(또는 반은 기록된) 순간에 읽으려고 하면 매우 문제가 될 수 있습니다! 원자 및 비 원자는 이 문제를 다른 방식으로 처리하는 데 도움이 됩니다.

먼저 질문을 읽은 다음 Bbum의 답변 을 읽으십시오. 또한 내 요약을 읽으십시오.


atomic 는 항상 보장합니다

  • 서로 다른 두 사람이 동시에 읽고 쓰기를 원하면 종이가 타지 않을 것입니다! --> 경쟁 조건에서도 응용 프로그램이 충돌하지 않습니다.
  • 한 사람이 쓰려고 하는데 8글자 중 4글자만 쓰면 중간에 읽을 수 없고, 8글자를 모두 써야만 읽기가 가능합니다. --> 에 읽기(get)가 발생하지 않습니다. '아직 쓰고 있는 쓰레드', 즉 쓸 바이트가 8바이트이고 4바이트만 쓰이면 그 순간까지는 쓰레드에서 읽을 수 없습니다. 그러나 충돌하지 않을 것이라고 말했기 때문에 자동 릴리스된 개체의 값에서 읽습니다.
  • 만약 당신이 이전에 종이에 작성하고 누군가가 여전히 읽을 수있는 읽기 싶어 한 것을 삭제 쓰기 전에. 어떻게? Mac OS 휴지통과 유사한 것을 읽을 것입니다(휴지통이 아직 100% 지워지지 않았기 때문에...변덕에 있습니다) ---> ThreadB가 이미 쓰기 할당을 해제한 상태에서 ThreadA가 읽는다면 다음과 같이 표시됩니다. ThreadB에 의해 완전히 작성된 최종 값에서 값을 얻거나 autorelease 풀에서 무언가를 얻습니다.

Retain count는 Objective-C에서 메모리를 관리하는 방식입니다. 개체를 생성할 때 개체의 유지 횟수는 1입니다. 개체에 유지 메시지를 보내면 개체의 유지 횟수가 1씩 증가합니다. 개체에 릴리스 메시지를 보내면 개체의 유지 횟수가 1만큼 감소합니다. 객체에 autorelease 메시지를 보내면 그 보유 횟수는 미래의 어떤 단계에서 1만큼 감소합니다. 객체의 보유 횟수가 0으로 줄어들면 할당이 해제됩니다.

  • Atomic 은 스레드 안전성을 보장하지 않지만 스레드 안전성을 달성하는 데 유용합니다. 스레드 안전성은 코드 작성 방법/읽고/쓰기 중인 스레드 대기열과 관련이 있습니다. 충돌하지 않는 멀티스레딩만 보장합니다.

뭐?! 멀티스레딩과 스레드 안전성은 다른가요?

예. 멀티스레딩은 여러 스레드가 동시에 공유 데이터 조각을 읽을 수 있으며 충돌이 일어나지는 않지만 자동 해제되지 않은 값에서 읽지 않는다는 것을 보장하지는 않습니다. 스레드 안전성을 사용하면 읽은 내용이 자동으로 해제되지 않습니다. 기본적으로 모든 것을 원자성으로 만들지 않는 이유는 성능 비용이 있고 대부분의 경우 스레드 안전성이 실제로 필요하지 않기 때문입니다. 우리 코드의 몇몇 부분에 그것을 필요로 하고 그 몇몇 부분에 대해서는 잠금, 뮤텍스 또는 동기화를 사용하여 스레드로부터 안전한 방식으로 코드를 작성해야 합니다.


nonatomic

  • Mac OS 휴지통과 같은 것은 없기 때문에 항상 값을 가져오는지(<-- 이것은 잠재적으로 충돌로 이어질 수 있음) 여부에 관심이 없고, 글을 중간에 읽으려고 해도 아무도 신경 쓰지 않습니다(비록 메모리에 중간에 쓰는 것은 종이에 중간에 쓰는 것과 매우 다릅니다. 메모리에 기록하면 이전과 같은 어리석은 가치를 줄 수 있지만 종이에는 기록된 내용의 절반만 볼 수 있습니다.) --> 충돌이 일어나지 않는다는 보장이 없기 때문에 자동 해제 메커니즘을 사용하지 않습니다.
  • 전체 쓰여진 값을 읽을 수 있다고 보장하지 않습니다!
  • 원자보다 빠름

전반적으로 두 가지 측면에서 다릅니다.

  • 자동 릴리스 풀의 유무로 인해 충돌이 발생하거나 발생하지 않습니다.

  • '아직 쓰기가 완료되지 않았거나 값이 비어 있는' 중간에 바로 읽기를 허용하거나 값이 완전히 쓰여졌을 때만 읽기를 허용하지 않고 허용합니다.


Honey

원자성 원자(기본값)

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


Suraj K Thomas

원자 속성은 얼마나 많은 스레드가 getter 및 setter를 수행하는지에 관계없이 완전히 초기화된 값을 유지하도록 합니다.

nonatomic 속성은 합성된 접근자가 값을 직접 설정하거나 반환하도록 지정하며, 동일한 값이 다른 스레드에서 동시에 액세스되는 경우 어떤 일이 발생하는지 보장하지 않습니다.


Laxman Sahni

원자성은 한 번에 하나의 스레드만 변수에 액세스할 수 있음을 의미합니다(정적 유형). Atomic은 스레드로부터 안전하지만 느립니다.

Nonatomic은 여러 스레드가 동시에 변수에 액세스할 수 있음을 의미합니다(동적 유형). Nonatomic은 스레드로부터 안전하지 않지만 빠릅니다.


Kemo

진실은 스핀 잠금을 사용하여 원자 속성을 구현한다는 것입니다. 아래와 같은 코드:

 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); }

paul

한 줄로:

Atomic 은 스레드로부터 안전합니다. Nonatomic 은 스레드로부터 안전하지 않습니다.


Taspiya Maisha

원자성을 사용하는 경우 스레드가 안전하고 읽기 전용임을 의미합니다. 비원자성을 사용하는 경우 다중 스레드가 변수에 액세스하고 스레드가 안전하지 않지만 빠르게 실행되고 읽기 및 쓰기 작업이 수행됨을 의미합니다. 이것은 동적 유형입니다.


Preetha

Atomic: NSLOCK을 사용하여 스레드를 잠궈 스레드 안전성을 보장합니다.

비 원자성: 스레드 잠금 메커니즘이 없기 때문에 스레드 안전성을 보장하지 않습니다.


satisharyan

전체 혼란을 단순화하기 위해 뮤텍스 잠금을 이해합시다.

Mutex 잠금은 이름에 따라 개체의 가변성을 잠급니다. 따라서 클래스가 개체에 액세스하면 다른 클래스는 동일한 개체에 액세스할 수 없습니다.

iOS에서 @sychronise 는 뮤텍스 잠금도 제공합니다. 이제 FIFO 모드에서 작동하며 흐름이 동일한 인스턴스를 공유하는 두 클래스의 영향을 받지 않도록 합니다. 그러나 작업이 기본 스레드에 있는 경우 UI를 유지하고 성능을 저하시킬 수 있으므로 원자 속성을 사용하여 개체에 액세스하지 마십시오.


Suryanarayan Sahu

원자 속성 :- 원자 속성이 할당된 변수는 단 하나의 스레드 액세스 권한을 가지며 스레드로부터 안전하고 성능 관점에서 우수하다는 것을 의미하며 기본 동작을 갖습니다.

비 원자 속성 :- 다중 스레드 액세스가 있고 스레드로부터 안전하지 않고 성능 관점에서 느릴 것임을 의미하는 원자 속성이 할당된 변수는 기본 동작을 가지며 두 개의 다른 스레드가 동시에 변수에 액세스하려고 할 때 의외의 결과를 줄 것입니다.


ashish.surana

출처 : http:www.stackoverflow.com/questions/588866/whats-the-difference-between-the-atomic-and-nonatomic-attributes

반응형