오류 : 쓰기 가능한 원자 속성이 합성 된 setter / getter와 사용자 정의 setter / getter를 쌍으로 연결할 수 없습니다


128

최근에 오래된 Xcode 프로젝트를 컴파일하려고 시도했지만 (잘 컴파일하는 데 사용됨) 이제이 형식의 오류가 많이 발생합니다.

error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter

이러한 오류를 일으키는 코드 패턴은 항상 다음과 같습니다.

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

@synthesize someProperty; // to provide the getter
- (void)setSomeProperty:(NSObject *)newValue
{
    //..
}

오류가 생성되는 이유를 알 수 있습니다. 컴파일러에 내 속성 접근 자 (getter 및 setter)를 합성하도록 지시 한 후 즉시 setter를 수동으로 재정의합니다. 그 코드는 항상 약간 냄새가났다.

그렇다면 이것을 수행하는 올바른 방법은 무엇입니까? @dynamic대신에 사용 @synthesize하면 getter도 작성해야합니다. 그게 유일한 방법인가요?


이것은 atomic속성 에서만 발생합니까 ? 원자 속성의 경우 잠금 전략과 관련하여 게터 / 세터 쌍을 동기화 상태로 유지하는 것이 좋습니다. 한 부분은 합성되고 다른 부분은 사용자 정의 코드 인 경우 어렵습니다.
Nikolai Ruhe

속성을 비 원자화하면 확실히 사라집니다. 흥미 롭군 동기화 문제에 대해서는 생각조차하지 않았습니다.
e.James

정확한 주제에 대한 해결책을 찾기 위해이 주제를 방문했습니다. 나는 게터와 세터를 혼자서 쓰고 싶지 않습니다. 잘…
Constantino Tsarouhas 16:13에

기본적으로 모든 속성은 원 자성이므로 명시 적으로 비원 자적으로 만들어야합니다. 원자 속성은 스레드로부터 안전하므로 스레드 안전 기능을 변경하기 때문에 setter 및 getter를 구현할 수 없습니다. 이 오류가 발생하는 이유를 알 수 있기를 바랍니다.
Mohd Haider

답변:


218

나는 같은 문제가 있었고 약간의 연구를 한 후에이 문제에 대한 결론을 내 렸습니다.

컴파일러는 키워드 @property를 생략하여 원자로 선언 한 것에 대해 경고 nonatomic하지만 해당 속성에 대한 액세스를 동기화하는 방법에 대한 불완전한 구현을 제공합니다.

그 경고를 사라지게하려면 :

a @property를 원자로 선언 하면 다음 중 하나를 수행하십시오.

  • 사용 @dynamic또는;
  • @synthesize합성 된 세터 및 게터를 사용 및 유지하거나;
  • 의 수동 구현을 제공 모두 세터와 (상기 지시자를 사용하지 않음)을 게터.

@propertywith (nonatomic)를 선언하면 getter 및 setter의 수동 및 합성 구현을 혼합 할 수 있습니다.

업데이트 : 속성 자동 합성에 대한 참고 사항

LLVM 4.0부터 CLang은 선언되지 않은 속성에 대해 자동 합성을 제공합니다 @dynamic. 기본적으로를 제외하더라도 @synthesize컴파일러는 getter 및 setter 메소드를 제공합니다. 그러나, 원자 속성에 대한 규칙은 여전히 동일합니다 : 하나는 컴파일러가 제공하자 모두 게터와 세터를, 또는 그 구현 모두에게 자신을!


감사! "비원
자형으로

14

getter도 구현해야합니다. 예:

// Interface:

@property (retain) NSObject * someProperty;

// Implementation:

- (void)setSomeProperty:(NSObject *)newValue
{
    @synchronized (self)
    {
        // ...
    }
}

- (NSObject *)someProperty
{
    NSObject *ret = nil;

    @synchronized (self)
    {
        ret = [[someProperty retain] autorelease];
    }

    return ret;
}

12

"객관적 C 사용자 정의 특성"을 검색하면 얻을 수있는 다른 인기 항목 중에서이 질문은 "setter ="또는 "getter ="에 대한 정보로 업데이트되지 않습니다.

따라서이 질문에 대한 자세한 정보를 제공하려면

당신은 서면으로 자신의 방법으로 @property 호출을 제공 할 수 있습니다

    @property(setter = MySetterMethod:, getter = MyGetterMethod)

제공된 setter 메소드의 콜론을 확인하십시오.

참조 애플 문서

편집 : Objective-C의 속성에 대한 새로운 변경 사항 (이제는 훨씬 더 지능적 임) 이이 질문에 대한 답변을 어떻게 변경하는지 잘 모르겠습니다. 아마도 모두 오래된 것으로 표시되어야합니다.


setter 메소드를 설정해도 실제로 경고가 제거되지는 않습니다. 예 :-> "@property (할당, setter = setDelegate :) id delegate;" 이 경우 내가 할 수있는 일은 내 게터를 추가하거나 비 원자 속성을 추가하는 것입니다. 대리인을 '원자'로 설정한다는 점을 감안할 때 비 원자 속성을 갖는 것은 중요하지 않습니다. 이해합니다.
David van Dugteren

흥미 롭군 데이비드 Objective-C의 "버전"은 무엇입니까 (XCode 버전이 더 도움이된다고 가정합니다)? 최근 iOS 6의 Objective-C 변경 사항이 무엇에 영향을 미치는지 잘 모르겠습니다.
Matias Forbord

0

OP가 설명 한 이유가 아닌이 오류가 발생하는 다른 사람들에게는 나와 같은 문제가있을 수 있습니다.

-() 메소드와 이름이 같은 @property가 있습니다.

이 같은:

@property UIView *mainView;

-(UIView *)mainView;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.