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

최근에 오래된 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도 작성해야합니다. 그게 유일한 방법인가요?



답변

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

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

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

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

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

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

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

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


답변

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


답변

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

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

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

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

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

참조 애플 문서

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


답변

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

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

이 같은:

@property UIView *mainView;

-(UIView *)mainView;


답변