시맨틱 이슈 : Property의 합성 게터는 '소유 한'객체를 반환하기 위해 Cocoa 명명 규칙을 따릅니다.


283

현재 iOS 5 SDK를 사용하여 앱을 개발하려고합니다. NSString을 속성으로 만들고 .m 파일에서 합성하려고합니다 (이전에 문제없이 수행했습니다). "의미 적 문제 : 속성의 합성 게터는 '소유 한'객체를 반환하기 위해 Cocoa 명명 규칙을 따릅니다."

이것은 내 코드입니다 : .h

@interface ViewController : UIViewController {
     NSString *newTitle;
}
@property (strong, nonatomic) NSString *newTitle;

.미디엄

@synthesize newTitle;

아무도 내가 이것을 고칠 수있는 단서가 있습니까? 감사!!


"소유 한 '오브젝트를 반환하기위한 코코아 명명 규칙을 따르는 속성"과 매우 유사한 오류가있었습니다.
TMin

답변:


606

내 생각에 사용중인 컴파일러 버전 은 선언 된 속성, 특히 선언 된 속성의 접근 자에 대한 메모리 관리 규칙 을 따릅니다 .

이름이 "alloc", "new", "copy"또는 "mutableCopy"로 시작하는 메소드를 사용하여 오브젝트를 작성하면 오브젝트의 소유권을 갖습니다.

newTitle합성시 라는 속성은이라는 메서드를 생성 -newTitle하므로 경고 / 오류가 발생합니다. 속성에 -newTitle대한 getter 메소드 newTitle이지만 이름 지정 규칙은 이름이 시작하는 메소드가 new호출자가 소유 한 오브젝트를 리턴하며 getter 메소드의 경우가 아니라고 명시합니다.

다음을 통해이 문제를 해결할 수 있습니다.

  1. 해당 속성 이름 바꾸기 :

    @property (strong, nonatomic) NSString *theNewTitle;
  2. 특성 이름을 유지하고 특수 메소드 이름 접 두부 중 하나로 시작하지 않는 게터 이름을 지정하십시오.

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
  3. 속성 이름과 getter 이름을 모두 유지하고 getter 이름이로 시작하더라도 메서드 제품군과 달리 메서드 제품군에 new속 한다고 컴파일러에 알려줍니다 .nonenew

    #ifndef __has_attribute
    #define __has_attribute(x) 0  // Compatibility with non-clang compilers
    #endif
    
    #if __has_attribute(objc_method_family)
    #define BV_OBJC_METHOD_FAMILY_NONE __attribute__((objc_method_family(none)))
    #else
    #define BV_OBJC_METHOD_FAMILY_NONE
    #endif
    
    @interface ViewController : UIViewController
    @property (strong, nonatomic) NSString *newTitle;
    - (NSString *)newTitle BV_OBJC_METHOD_FAMILY_NONE;
    @end
    

    이 솔루션을 사용하면 newTitle속성 이름과 게터 이름을 모두 유지할 -newTitle수 있지만 호출자가 소유 한 객체를 반환하지 않는 메서드를 호출 하면 코드를 읽는 다른 사람들에게 혼란을 줄 수 있습니다.


기록을 위해 애플은 ARC 릴리즈 노트로의 전환을 발표했다 .

속성으로 new또는로 시작하는 이름을 지정할 수 없습니다 copy.

그들은 이미 그들의 진술이 정확하지 않다는 통보를 받았습니다. 범인은 속성 이름이 아닌 게터 메소드 이름입니다.


편집 2015 년 1 월 17 일 : 방금 속성 이름이 특수 메소드 패밀리 접두사 중 하나와 일치하는 일반적인 경우에 대해 수정을 포함 하여 위의 옵션 3을 제안 하는 Clang에 대한 최근 커밋을 보았습니다 objc_method_family(none). Xcode는 결국이 변경 사항을 통합 할 것입니다.


6
매력 남자처럼 일했다!! 감사!!! 나중에 참조하기 위해- "@property (strong, nonatomic, getter = theNewTitle) NSString * newTitle;"을 사용했습니다.
노암

8
훌륭한 답변입니다. 접두사가 "new"인 변수가있었습니다.

나도이 문제가있어서 많은 시간을 낭비합니다! 당신은 정말 천재입니다 ~ 감사합니다!
H Lai

NS_RETURNS_NOT_RETAINED당신도 필요한 것입니다.
DawnSong

55

허용되지 않는 개체 이름

  • newButton
  • copyLabel
  • allocTitle

허용 가능한 객체 이름

  • neueButton
  • mCopyLabel
  • _allocTitle

#arc # 자동 합성 # xcode-4.6.1

** 편집하다 **

분명히 mutableCopy 를 사용할 수 없습니다 .


1
또한 현재로서는 "복사"를 사용할 수 없습니다.
Rishab

30

new로 시작하는 멤버의 이름은 경고를 트리거하는 것입니다. 이름을 editedTitle로 변경하면 경고가 사라집니다. 나는 이것을 확인하는 문서를 찾을 수 없었지만 테스트를 통해 'new'로 시작하는 멤버 변수가 컴파일러를 악화시키는 지 확인할 수있었습니다.


8

ARC는 속성 이름에 "New ...."를 사용할 수 없습니다. 그러나 getter 이름을 변경하여 "newTitle"을 사용할 수 있습니다.

@property (nonatomic, strong, getter=theNewTitle) NSString *newTitle;

6

Bavarious가 제안한 것이 당신이하고 싶었던 것처럼 보이지 않습니다. 인스턴스 변수를 선언 NewTitle하고 속성을 합성하기 만하면됩니다. 예전에는 인스턴스 변수와 속성을 선언해야했습니다. 더 이상은 없어.

이제 올바른 방법은 다음과 같습니다.

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.미디엄

@synthesize newTitle = _newTitle; // Use instance variable _newTitle for storage

속성의 인스턴스 변수 newTitle가 합성됩니다. 인스턴스 변수가 속성과 동일하지 않기 때문에 실수하기가 너무 쉽습니다 .

예 : 속성 선언 및 접근 자 합성을 참조하십시오 .


컴파일러 버전에 따라 다릅니다. 이 경우 최신 버전의 clang은 경고를 표시하므로 내 대답에서 컴파일러 버전을 언급했습니다.

나는 당신이 문제를 해결했다고 생각하지 않습니다. Xcode 9의 경우 경고가 아니라 오류입니다. NS_RETURNS_NOT_RETAINED당신이 필요한 것입니다.
DawnSong

4

CoreData에서 속성 (일반 컴파일)에 "new ..."를 사용하면 "잘못된 액세스"예외와 함께 임의로 충돌합니다.

충돌 로그가 없으며 "All Exceptions Breakpoint"로 표시된 줄이 전혀 도움이되지 않습니다.


3

속성과 동일한 이름으로 세터를 작성하면이 경고가 제거됩니다.


Xcode 7.3에서는 이것이 도움이되지 않았습니다. 속성 정의 줄에 여전히 오류가 나타납니다.
arlomedia

1

속성 이름 앞에 "new"를 사용할 수 없거나 사용할 수없는 문제 외에 한 가지 더 말해 보겠습니다. 이름 앞에 "new"를 사용하지 마십시오. "신규"는 시간에 따라 다릅니다. 현재는 새로운 것이지만 얼마 후 새로운 것을 다시 구현하고 싶을 수도 있습니다. 따라서 이름에 "new"를 사용하는 것은 항상 나쁩니다. 프로그래밍 세계에서 "새로운 것"은 항상 무언가를 창조합니다.

귀하의 경우 다른 제목을 지정하지 않고 현재 이름을 property titleReplacement로 지정하십시오.

한 가지 더 : setSomething 또는 getSomething과 같이 동사로 함수와 메소드의 이름을 먼저 지정하십시오. 그러나 속성에서 heightMinimum, heightMaximum 등과 같이 객체의 이름을 먼저 지정하십시오. 코딩 할 때 관리자를 사용할 때는 항상 객체를 찾습니다. 사용해보십시오. ;-)


1

NS_RETURNS_NOT_RETAINED 명명 문제를 해결하는 데 사용됩니다.

@property (nonatomic, copy) NSString *newTitle NS_RETURNS_NOT_RETAINED;

우리는 찾을 수있는 정의를 다음과 같이

#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

'ns_returns_not_retained'속성은 'ns_returns_retained'의 보완입니다. 함수 나 메소드가 Cocoa 규약을 준수하고 보유 된 Cocoa 객체를 리턴하는 것처럼 보일 수있는 경우,이 속성은 리턴 된 객체 참조가 호출자에게 리턴되는 "소유"참조로 간주되지 않아야 함을 표시하는 데 사용될 수 있습니다. Foundation 프레임 워크는 아래 표시된 것과 기능적으로 동일한 매크로 NS_RETURNS_NOT_RETAINED를 정의합니다.

자세한 내용은 여기에 첨부 하십시오.


-2

이 시도:-

@property (nonatomic,retain) NSString *newTitle;

1
여전히 똑같은 문제입니다. 참고로 오류 줄은 @synthesize 줄에 있습니다.
노암
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.