문제

무엇을 하는가? atomic 그리고 nonatomic 속성 선언의 의미는 무엇입니까?

@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;

이 세 가지의 운영상의 차이점은 무엇입니까?

도움이 되었습니까?

해결책

마지막 두 가지는 동일합니다. "원자"는 기본 동작입니다 (실제로 키워드가 아닙니다. 부재에 의해서만 지정됩니다 nonatomic -- atomic 최근 버전의 LLVM/Clang에서 키워드로 추가되었습니다).

메소드 구현을 @Synthesizy한다고 가정하면 Atomic과 비 원자는 생성 된 코드를 변경합니다. 자신의 세터/getters를 작성하는 경우 원자/비 원자/비 원자/퇴직/할당/사본은 단지 권고입니다. (참고 : @synthesize는 이제 LLVM의 최근 버전에서 기본 동작입니다. 인스턴스 변수를 선언 할 필요도 없으며 자동으로 합성되며 _ 우발적 인 직접 액세스를 방지하기 위해 이름으로 선정되었습니다).

"Atomic"을 사용하여 합성 된 세터/게터는 전부의 값은 다른 스레드의 세터 활동에 관계없이 항상 getter에서 반환되거나 세터에 의해 설정됩니다. 즉, 스레드 A가 getter의 중간에있는 동안 스레드 B가 세터를 호출하는 경우 실제 생존 값 (AutoreLeded Object)은 A의 발신자에게 반환됩니다.

~ 안에 nonatomic, 그러한 보증은 없습니다. 따라서, nonatomic "원자"보다 상당히 빠릅니다.

"원자"가하는 일 ~ 아니다 DO는 스레드 안전에 대한 보장을 제공하는 것입니다. 스레드 A가 다른 값으로 세터를 호출하는 스레드 B와 C와 동시에 getter를 호출하는 경우, 스레드 A는 세 가지 값 중 하나를 반환 할 수 있습니다. B와 C에서 마찬가지로, 물체는 B 또는 C의 값으로 끝날 수 있으며 말할 방법이 없습니다.

다중 스레드 프로그래밍의 주요 과제 중 하나 인 데이터 무결성 보장은 다른 방법으로 달성됩니다.

이것에 추가 :

atomicity 단일 속성 중 다중 종속 속성이 작동하는 경우 스레드 안전을 보장 할 수 없습니다.

고려하다:

 @property(atomic, copy) NSString *firstName;
 @property(atomic, copy) NSString *lastName;
 @property(readonly, atomic, copy) NSString *fullName;

이 경우 스레드 A는 setFirstName: 그리고 전화 setLastName:. 그 동안 스레드 B가 호출 할 수 있습니다 fullName Thread A의 두 호출 사이에서 이전 이름과 함께 새 이름을 받게됩니다.

이를 해결하려면 a가 필요합니다 거래 모델. 즉, 액세스를 제외 할 수있는 다른 종류의 동기화 및/또는 제외 fullName 종속 속성이 업데이트되고 있습니다.

다른 팁

이것은 Apple의 설명입니다 선적 서류 비치, 그러나 아래는 실제로 일어나는 일의 몇 가지 예입니다. "원자"키워드가 없으며 "비 원자"를 지정하지 않으면 속성이 원자력이지만 "원자"를 명시 적으로 지정하면 오류가 발생합니다.

//@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으로 떨어집니다.

속성이 스칼라 값인지 객체인지 여부에 따라 이러한 것들이 어떻게 작동하는지, 그리고 보유, 복사, 읽기, 비 원자 등의 상호 작용에 따라 이러한 것들이 어떻게 작동하는지에 대한 많은 다른 변형이 있습니다. 일반적으로 속성 신디사이저는 모든 조합에 대해 "올바른 일"을 수행하는 방법을 알고 있습니다.

원자

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

비 원자

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

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

"이름"이라는 원자 문자열 속성이 있다고 가정하고 [self setName:@"A"] 스레드 A에서 전화를 걸어 [self setName:@"B"] 스레드 B에서 전화하십시오 [self name] 스레드 C에서, 다른 스레드의 모든 작업은 일련의 연속으로 수행되므로 한 스레드가 세터 나 getter를 실행하는 경우 다른 스레드가 대기됩니다.

이것은 속성 "이름"을 읽고 쓰기 안전하지만 다른 스레드 인 D, 호출 [name release] 동시에이 작업은 여기에 세터/getter 호출이 없기 때문에 충돌이 발생할 수 있습니다. 즉, 객체가 읽기/쓰기 안전 (Atomic)이지만 다른 스레드가 모든 유형의 메시지를 객체에 보낼 수 있으므로 스레드 안전이 아닙니다. 개발자는 그러한 객체에 대한 스레드 안전성을 보장해야합니다.

속성 "이름"이 비 원자 인 경우 위의 예제 -A, B, C 및 D의 모든 스레드는 예측할 수없는 결과를 동시에 실행합니다. 원자의 경우 A, B 또는 C 중 하나가 먼저 실행되지만 D는 여전히 병렬로 실행될 수 있습니다.

구문과 의미론은 이미이 질문에 대한 다른 훌륭한 답변에 의해 잘 정의되어 있습니다. 왜냐하면 실행 그리고 성능 자세한 내용은 좋지 않습니다. 대답을 추가하겠습니다.

이 3의 기능적 차이는 무엇입니까?

나는 항상 원자를 기본적으로 호기심으로 간주했습니다. 추상화 수준에서, 우리는 100% 스레드 안전성을 달성하기위한 차량으로 클래스에 원자 속성을 사용하는 것이 코너 케이스입니다. 진정으로 올바른 멀티 스레드 프로그램의 경우, 프로그래머의 개입은 거의 확실히 요구 사항입니다. 한편, 성능 특성과 실행은 아직 자세히 설명되지 않았습니다. 수년에 걸쳐 많은 멀티 스레드 프로그램을 작성한 후, 나는 내 재산을 다음과 같이 선언했습니다. nonatomic 원자가 어떤 목적으로도 합리적이지 않았기 때문에 전체 시간. 원자 및 비 원자 특성의 세부 사항에 대한 논의 중 이 질문, 나는 약간의 프로파일 링이 호기심 많은 결과를 낳았습니다.

실행

확인. 가장 먼저 정리하고 싶은 것은 잠금 구현이 구현 정의 및 추상적이라는 것입니다. 루이를 사용합니다 @synchronized(self) 그의 예에서 - 나는 이것을 일반적인 혼란의 원천으로 보았다. 구현은 그렇지 않습니다 실제로 사용 @synchronized(self); 객체 레벨을 사용합니다 스핀 잠금 장치. Louis의 그림은 우리 모두가 익숙한 구성을 사용하여 고급 삽화에 적합하지만 사용하지 않는다는 것을 아는 것이 중요합니다. @synchronized(self).

또 다른 차이점은 원자 특성이 getter 내에서 객체를 유지/방출한다는 것입니다.

성능

흥미로운 부분은 다음과 같습니다. 원자 속성을 사용하는 성능 논쟁의 여지가 없습니다 (예 : 단일 스레드) 사례는 경우에 따라 매우 빠를 수 있습니다. 이상적이지 않은 경우 원자 액세스를 사용하면 오버 헤드의 20 배 이상이 소요될 수 있습니다. nonatomic. 동안 경쟁 7 스레드를 사용하는 경우 3 바이트 구조물에 대해 44 배 느 렸습니다 (2.2GHz 핵심 i7 쿼드 코어, x86_64). 3 바이트 구조물은 매우 느린 속성의 예입니다.

흥미로운 참고 사항 : 3 바이트 구조물의 사용자 정의 액세서는 합성 된 원자 액세서보다 52 배 빠릅니다. 또는 합성 된 비 원자 액세서의 속도의 84%.

경쟁 사례의 물체도 50 배를 초과 할 수 있습니다.

구현의 최적화 및 변동의 수로 인해 이러한 상황에서 실제 영향을 측정하는 것은 매우 어렵습니다. 당신은 종종 "당신이 프로필을 신뢰하고 그것이 문제라고 생각하지 않는 한 신뢰할 수 있습니다"와 같은 것을들을 수 있습니다. 추상화 수준으로 인해 실제로 실제 영향을 측정하는 것은 매우 어렵습니다. 프로필에서 실제 비용을 모으는 데 시간이 많이 걸리고 추상화로 인해 매우 부정확 할 수 있습니다. 또한 ARC 대 MRC는 큰 차이를 만들 수 있습니다.

그래서 물러 서자. ~ 아니다 부동산 액세스 구현에 중점을두면 우리는 다음과 같은 일반적인 용의자를 포함합니다. objc_msgSend, 많은 전화에 대한 실제 고급 결과를 조사하고 NSString getter in 논쟁의 여지가 없습니다 사례 (초의 값) :

  • MRC | 비 원자 | 수동으로 구현 된 게터 : 2
  • MRC | 비 원자 | 합성 된 게터 : 7
  • MRC | 원자 | 합성 된 게터 : 47
  • 아크 | 비 원자 | 합성 게터 : 38
  • 아크 | 원자 | 합성 된 게터 : 47

당신이 추측했듯이, 참조 수 활동/사이클링은 원자력과 아크 아래의 중요한 기여자입니다. 또한 논쟁의 여지가있는 경우에 더 큰 차이가 있습니다.

성능에 세심한주의를 기울이지 만 여전히 말합니다. 의미론 첫 번째!. 한편, 성능은 많은 프로젝트에서 우선 순위가 낮습니다. 그러나 사용하는 기술의 실행 세부 사항과 비용을 아는 것은 확실히 아프지 않습니다. 귀하의 요구, 목적 및 능력에 적합한 기술을 사용해야합니다. 바라건대, 이렇게하면 몇 시간의 비교를 절약하고 프로그램을 설계 할 때 더 나은 정보를 결정하는 데 도움이됩니다.

원자 = 스레드 안전

비 원자 = 스레드 안전이 없습니다

스레드 안전 :

인스턴스 변수는 런타임 환경에서 해당 스레드의 실행 스케줄링 또는 인터리브에 관계없이 여러 스레드에서 액세스 할 때 올바르게 작동하는 경우 스레드 안전입니다.

우리의 맥락에서 :

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

사용 장소 atomic:

인스턴스 변수가 멀티 스레드 환경에서 액세스하는 경우.

의 의미 atomic:

빠르지 않습니다 nonatomic 왜냐하면 nonatomic 런타임에서 워치 독 작업이 필요하지 않습니다.

사용 장소 nonatomic:

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

나는 원자력 및 비 원자 특성에 대한 꽤 잘 설명 된 것을 발견했습니다. 여기. 다음은 동일한 것의 관련 텍스트입니다.

'원자'는 분해 될 수 없다는 것을 의미합니다. OS/프로그래밍 용어에서 원자 함수 호출은 중단 될 수없는 호출입니다. 전체 기능을 실행해야하며 OS의 일반적인 컨텍스트 전환으로 CPU에서 교체되지 않아야합니다. 모르는 경우 : CPU는 한 번에 한 가지만 수행 할 수 있으므로 OS는 CPU에 대한 액세스를 거의 실행중인 모든 공정으로 회전시켜 환각 멀티 태스킹의. CPU 스케줄러는 실행 중 어느 시점에서도 중간 함수 호출에서도 프로세스를 방해 할 수 있습니다. 따라서 두 프로세스가 변수를 동시에 업데이트하려고 시도 할 수있는 공유 카운터 변수를 업데이트하는 것과 같은 조치의 경우, '원자 적으로'실행해야합니다. 즉, 각 업데이트 조치는 다른 프로세스를 CPU.

따라서이 경우 원자는 속성 판독기 메소드가 중단 될 수 없다는 것을 의미합니다. 실제로 다른 스레드/호출/함수가 가져 오기 때문에 메소드에 의해 읽는 변수가 값을 반으로 변경할 수 없음을 의미합니다. CPU로 교체했습니다.

때문에 atomic 변수는 중단 될 수 없으며, 어느 시점에서나 그 값이 포함 된 값은 부패하지 않았습니다, 그러나이 스레드 잠금 장치가 더 느리게 액세스 할 수 있도록합니다. non-atomic 반면에 변수는 그러한 보장을하지 않지만 더 빠른 접근의 사치를 제공합니다. 요약하려면 함께 가십시오 non-atomic 변수가 여러 스레드에 의해 동시에 액세스되지 않고 속도를 높이는 것을 알고 있으면 속도를 높입니다.

너무 많은 기사를 읽고, 오버플로 게시물을 스택하고, 가변 속성 속성을 확인하기 위해 데모 애플리케이션을 작성 한 후에 모든 속성 정보를 하나로 묶기로 결정했습니다.

  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 기본 동작입니다
    • 비 쓰레기 수집 된 환경 (즉, Retain/Release/AutoreLease를 사용할 때)의 원자 액세서는 다른 스레드가 올바른 설정/값을 얻지 않도록 잠금을 사용합니다.
    • 실제로 키워드가 아닙니다.

    예시:

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

    • nonatomic 다중 스레드가 변수 (동적 유형)에 액세스하는 것을 의미합니다.
    • nonatomic 스레드-유추입니다.
    • 그러나 성능이 빠릅니다
    • nonatomic 기본 동작이 아닙니다. 추가해야합니다 nonatomic 속성 속성의 키워드.
    • 두 개의 다른 프로세스 (스레드)가 동시에 동일한 변수에 액세스 할 때 예기치 않은 동작이 발생할 수 있습니다.

    예시:

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

원자 :

원자가는 속성에 대한 접근이 원자 방식으로 수행 될 것을 보장합니다. 예를 들어, 항상 완전히 초기화 된 객체를 반환합니다. 한 스레드의 속성을 얻거나 세트를 작성해야합니다.

두 스레드에서 다음과 같은 기능이 한 번에 발생한다고 상상하면 결과가 왜 예쁘지 않은지 알 수 있습니다.

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

장점 :매우 빠른 실행.

단점 :멀티 스레딩의 경우 쓰레기 가치의 가능성.

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

비 쓰레기 수집 된 환경 (즉, Retain/Release/AutoreLease를 사용할 때)의 원자 액세서는 다른 스레드가 올바른 설정/값을 얻지 않도록 잠금을 사용합니다.

"보기"성능과 스레딩"Apple의 Objective-C 2.0 문서 섹션은 다중 스레드 앱을 만들 때 더 많은 정보 및 기타 고려 사항에 대해서는 문서입니다.

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

비 원자는 여러 스레드가 변수 (동적 유형)에 액세스한다는 것을 의미합니다. 비 원자는 스레드-미니이지만 빠릅니다.

원자입니다 스레드 안전합니다, 그것은이다 느린 그리고 그것 잘 알 수 없음 (보장되지 않음) 동일한 영역에서 액세스를 시도하는 스레드 수에 관계없이 잠긴 값 만 제공됩니다. Atomic을 사용하는 경우이 기능 내부에 작성된 코드 조각이 중요한 섹션의 일부가되어 한 번에 한 스레드 만 실행할 수 있습니다.

스레드 안전 만 보장합니다. 그것은 그것을 보장하지 않습니다. 내 말은 당신은 당신이 당신의 자동차를위한 전문가 드라이버를 고용한다는 것입니다. 여전히 자동차가 사고를 충족하지 않을 것을 보장하지는 않습니다. 그러나 확률은 가장 작은 상태로 남아 있습니다.

원자 - 분해 할 수 없으므로 결과가 예상됩니다. 비 원자의 경우 - 다른 스레드가 메모리 영역에 액세스하면 수정할 수 있으므로 결과는 예상치 못한 일입니다.

코드 토크 :

Atomic Make Getter와 Setter의 Setter는 안전합니다. 예를 들어, 당신이 작성한 경우 :

self.myProperty = value;

스레드 안전합니다.

[myArray addObject:@"Abc"] 

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

그러한 키워드 "원자"가 없습니다.

@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;

키워드를 첫 번째 속성 속성으로 전혀 쓰지 않아도됩니다.

잊지 마십시오. 이것이 속성 전체가 스레드 안전하다는 것을 의미하지는 않습니다. 세터/getter의 메소드 호출 만 그러나 세터를 사용하고 그 후 두 개의 다른 스레드가있는 동시에 getter를 사용한다면, 그것은 또한 깨질 수 있습니다!

원자 (기본값)

원자는 기본값입니다. 아무것도 입력하지 않으면 속성이 원자입니다. 원자 속성은 읽기를 시도하면 유효한 값을 되 찾을 수 있습니다. 그것은 그 값이 무엇인지 보장하지는 않지만 정크 메모리뿐만 아니라 좋은 데이터를 되 찾을 수 있습니다. 이것이 허용 할 수있는 것은 단일 변수를 가리키는 여러 스레드 또는 여러 프로세스가있는 경우 한 스레드가 읽을 수 있고 다른 스레드가 쓸 수 있다는 것입니다. 그들이 동시에 치면, 독자 스레드는 변경 전 또는 변경 후에 두 값 중 하나를 얻을 수 있습니다. 원자가가 당신에게주지 않는 것은 어떤 종류의 가치를 얻을 수 있는지에 대한 보장입니다. Atomic은 일반적으로 스레드 안전과 혼동되며 이는 정확하지 않습니다. 스레드 안전을 다른 방법으로 보장해야합니다. 그러나 Atomic은 읽으려고하면 어떤 종류의 가치를 되 찾을 수 있다고 보장합니다.

비 원자

플립 측면에서, 비 원자는 아마도 당신이 추측 할 수 있듯이,“원자적인 일을하지 마십시오.”라고 의미합니다. 당신이 잃는 것은 당신이 항상 무언가를 되 찾을 수 있다는 것을 보장하는 것입니다. 글의 중간에 읽으려고하면 쓰레기 데이터를 되 찾을 수 있습니다. 그러나 반면에, 당신은 조금 더 빨리갑니다. 원자 속성은 가치를 되 찾을 것을 보장하기 위해 약간의 마법을해야하기 때문에 약간 느립니다. 그것이 당신이 많이 액세스하는 재산이라면, 당신은 당신이 그 속도 페널티를 발생시키지 않도록 비 원자로 떨어 뜨릴 수 있습니다.

자세히보기 : https://realm.io/news/tmi-objective-c-property-attributes/

다중 스레드 코드로 속성을 사용하는 경우 비 원자 속성과 원자 속성의 차이점을 볼 수 있습니다. 비 원자는 원자보다 빠르며 원자는 비 원자가 아닌 실로 안전합니다.

Vijayendra Tripathi는 이미 멀티 스레드 환경에 대한 모범을 보였습니다.

  • -원자는 하나의 스레드 만 변수 (정적 유형)에 액세스한다는 것을 의미합니다.
  • -원자력은 스레드 안전합니다.
  • -그러나 성능이 느립니다

선언하는 방법 :

원자가 기본이므로

@property (retain) NSString *name;

그리고 구현 파일에서

self.name = @"sourov";

세 가지 속성과 관련된 작업이 있다고 가정합니다

 @property (retain) NSString *name;
 @property (retain) NSString *A;
 @property (retain) NSString *B;
 self.name = @"sourov";

모든 속성은 (비동기 적으로와 같이) 평행합니다.

스레드에서 "이름"이라고 부르는 경우 ,

그리고

전화하면 동시에

[self setName:@"Datta"]

스레드에서 ,

이제 *이름 속성이 비 원자 인 경우 그 다음에

  • a에 대한 "datta"값을 반환합니다
  • b에 대한 "datta"값을 반환합니다

그렇기 때문에 비 원자력이 스레드가 안전하지 않지만 병렬 실행으로 인해 성능이 빠릅니다.

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

  • 그것은 "Sourov"의 가치를 보장 할 것입니다
  • 그러면 B에 대한 "datta"값을 반환합니다.

그렇기 때문에 원자를 스레드 안전이라고합니다 그리고그렇기 때문에 Read-Write Safe라고합니다

이러한 상황 운영은 연속적으로 수행됩니다. 성능이 느립니다

- 비 원자는 다중 스레드가 변수 (동적 유형)에 액세스하는 것을 의미합니다.

- 비 원자는 실 안전하지 않습니다.

- 그러나 성능이 빠릅니다

-Nonatomic은 기본 동작이 아니므로 속성 속성에 비 원자 키워드를 추가해야합니다.

신속하게 신속한 특성이 OBJC 의미에서 비 원자임을 확인하기 때문입니다. 한 가지 이유는 프로페티 별 원자가가 귀하의 요구에 충분한 지 여부에 대해 생각하기 때문입니다.

참조: https://forums.developer.apple.com/thread/25642

자세한 정보는 웹 사이트를 방문하십시오http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html

시작하기 전에 : 메모리의 모든 객체는 새로운 작가가 발생하기 위해 메모리에서 거래해야한다는 것을 알아야합니다. 종이에서하는 것처럼 단순히 무언가를 쓸 수는 없습니다. 너 ~ 해야 하다 먼저 지우고 (Dealloc) 그것을 쓸 수 있습니다. 현재 지우기가 끝나거나 절반이 완료된 순간에 아무것도 아직 글을 썼거나 반복 썼고 당신은 그것을 읽으려고 노력합니다. 그것은 매우 문제가 될 수 있습니다! 원자 및 비 원자는이 문제를 다른 방식으로 치료하는 데 도움이됩니다.

먼저 읽었습니다 이것 질문하고 읽으십시오 BBUM의 대답. 또한 내 요약을 읽으십시오.


atomic 항상 보장 할 것입니다

  • 두 명의 다른 사람들이 동시에 읽고 쓰기를 원한다면 종이가 타지 않을 것입니다! -> 경주 조건에서도 응용 프로그램이 충돌하지 않습니다.
  • 한 사람이 글을 쓰려고하고 8 글자 중 4 글자 만 쓸만한 경우 중간에 읽을 수 없으며 8 글자가 모두 쓰여질 때만 읽을 수 있습니다. '여전히 쓰고있는 실', 즉 작성할 바이트에 8 바이트가 있고 4 바이트 만 쓰여진 경우 - 그 순간까지 읽을 수 없습니다. 그러나 나는 그것이 충돌하지 않을 것이라고 말했기 때문에 그것은 자동 릴리스 물체.
  • 만약에 ~ 전에 당신을 쓰십시오 가지다 이전에 종이에 쓰여진 것을 지우고 누군가가 당신을 읽고 싶어 ~할 수 있다 여전히 읽습니다. 어떻게? Mac OS Trash Bin과 비슷한 내용을 읽을 것입니다 (Trash Bin이 여전히 100% 지워지지 않기 때문에 ... 림보에 있습니다) ---> Trooidb가 이미 작성하여 글을 쓰기 위해 읽어야한다면 얻을 것입니다. ThreadB의 최종 완전 작성된 값의 값 또는 AutorElease Pool에서 무언가를 얻습니다.

유지 카운트는 대상 c에서 메모리가 관리되는 방식입니다. 객체를 생성 할 때 1은 1입니다. 객체를 보유하는 메시지를 보낼 때, 유지 카운트는 1에 의해 증가합니다. 개체를 보내십시오 자동 제출 메시지, 그 유지 수는 미래의 일부 단계에서 1 씩 감소합니다. 객체의 고정 수가 0으로 줄어든 경우 거래됩니다.

  • 원자 그렇지 않습니다 스레드 안전을 달성하는 데 유용하지만 스레드 안전을 보장합니다. 스레드 안전은 코드 작성 방법/ 읽기/ 쓰기 스레드 대기열과 관련이 있습니다. 무시할 수없는 멀티 스레딩 만 보장합니다.

뭐?! 멀티 스레딩 및 실 안전 다른?

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


nonatomic

  • Mac OS Trash Bin과 같은 것은 없기 때문에 아무도 가치가 있는지 여부를 신경 쓰지 않습니다 (<- 이것은 잠재적으로 충돌로 이어질 수 있음) 또는 누군가가 글을 반쯤 읽으려고 할 때 아무도 신경 쓰지 않습니다 (그러나 기억에 반쯤 글을 쓰는 것은 종이에 대한 중간 글쓰기와는 매우 다릅니다. 기억에는 이전부터 미친 멍청한 가치를 줄 수 있지만 종이에는 쓰여진 것의 절반 만 볼 수 있습니다) -> 충돌하지 않도록 보장하지 않습니다. 자동 제출 메커니즘을 사용하지 않습니다.
  • 전체 서면 값을 읽도록 보장하지 않습니다!
  • 원자보다 빠릅니다

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

  • 자동 제출 풀이 있거나없는 이유로 충돌 여부.

  • '아직 완료되지 않은 쓰기 또는 빈 값'의 중간에 바로 읽을 수 있거나 허용하지 않으며 값이있을 때만 읽을 수 있습니다. 충분히 쓴.

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

비 원자 속성은 합성 된 액세서가 단순히 값을 직접 설정하거나 반환하도록 지정하며, 다른 스레드에서 동일한 값에 동시에 액세스 할 경우 어떻게되는지 보장하지 않습니다.

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

비 원자는 여러 스레드가 동시에 변수에 액세스 할 수 있음을 의미합니다 (동적 유형). 비 원자는 스레드-미니이지만 빠릅니다.

원자성 atomic (기본값)

원자가 기본값입니다.아무 것도 입력하지 않으면 속성이 원자.atomic 속성은 다음에서 읽으려고 하면 그러면 유효한 값을 다시 얻을 수 있습니다.어떠한 보증도 하지 않습니다 그 값이 무엇인지에 대해 말하지만 좋은 데이터를 얻을 수 있습니다. 그냥 정크 메모리.이것이 당신이 할 수있는 것은 당신이 여러 가지가있는 경우입니다. 스레드 또는 단일 변수를 가리키는 여러 프로세스, 하나 스레드는 읽을 수 있고 다른 스레드는 쓸 수 있습니다.그들이 동시에 치면 time, 판독기 스레드는 다음 두 값 중 하나를 얻도록 보장됩니다.변경 전이든 변경 후든 마찬가지입니다.원자가 아닌 것 give you는 당신이 그 가치 중 어느 것을 보증합니까? 얻을 수 있습니다.Atomic 은 실제로 일반적으로 스레드로부터 안전한 것과 혼동됩니다. 그리고 그것은 옳지 않습니다.스레드 안전성을 보장해야 합니다. 다른 방법.그러나 atomic은 읽으려고하면 당신은 어떤 종류의 가치를 되찾습니다.

비원자

반대로, 비원자적이라는 말은, 아마 짐작할 수 있듯이, "그런 원자 같은 짓은 하지 마." 당신이 잃는 것은 당신이 항상 뭔가를 되찾으세요.중간에 읽으려고 하면 쓰면 가비지 데이터를 다시 가져올 수 있습니다.그러나 다른 한편으로는 조금 더 빠르게.원자 속성은 마법을 부려야 하기 때문입니다 값을 되찾을 수 있도록 하기 위해 약간 느립니다.면 많이 접근하고 있는 속성이므로 떨어뜨리고 싶을 수도 있습니다 그 속도를 발생시키지 않도록 비원자성으로 내려갑니다. 벌.입장

예의 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

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

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

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

원자 특성 :- 원자 속성으로 할당 된 변수가 하나만 액세스 할 수 있고 스레드 안전이 안전하고 성능 관점에서 양호 할 경우 기본 동작이 있습니다.

비 원자 특성 :- 멀티 스레드 액세스가 있고 스레드가 안전하지 않고 성능 관점에서 느리게 진행되며 기본 동작이 있고 두 개의 다른 스레드가 동시에 변수에 액세스하려고하는 경우에도 스레드에 액세스 할 수 없으며 스레드가 안전하지 않으며 성능 관점이 느려질 때의 변수가 지정된 경우. 예상치 못한 결과.

전체 혼란을 단순화하려면 Mutex 잠금을 이해해야합니다.

Mutex Lock은 이름에 따라 물체의 돌연변이를 잠그는 것입니다. 따라서 객체에 클래스가 액세스하면 다른 클래스가 동일한 객체에 액세스 할 수 없습니다.

iOS에서 @sychronise 또한 FIFO 모드로 제공되는 MUTEX LOCK을 제공하며 유량이 동일한 인스턴스를 공유하는 두 클래스의 영향을받지 않도록합니다. 그러나 작업이 기본 스레드에있는 경우 Atomic Properties를 사용하여 객체에 액세스하지 않으므로 UI를 유지하고 성능을 저하시킬 수 있습니다.

원자 : NSLock을 사용하여 스레드를 잠그면 스레드 안전성을 확인하십시오.

비 원자 : 스레드 잠금 메커니즘이 없으므로 스레드 안전성을 보장하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top