意味上の問題:プロパティの合成ゲッターは、「所有された」オブジェクトを返すためのCocoa命名規則に従います


283

現在、iOS 5 SDKを使用してアプリを開発しています。私はNSStringをプロパティにして、それを.mファイルに合成しようとしています(以前に問題なくこれを実行しました)。今、私はこれに遭遇しました:「セマンティックの問題:プロパティの合成ゲッターは、「所有された」オブジェクトを返すためのCocoa命名規則に従います。」

これは私のコードです:.h

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

.m

@synthesize newTitle;

誰かが私がこれをどのように修正できるか手がかりを持っていますか?ありがとう!!


非常によく似たエラーが発生しました。「プロパティは「所有された」オブジェクトを返すためのCocoaの命名規則に従います」以下のBavariousの回答はこれも解決するようです。
TMin

回答:


606

私の推測では、使用しているコンパイラのバージョンは、宣言されたプロパティのメモリ管理規則にも従っています。具体的には、宣言されたプロパティのアクセサについても同様です。

名前が「alloc」、「new」、「copy」、または「mutableCopy」で始まるメソッドを使用して作成した場合、オブジェクトの所有権を取得します。

という名前のプロパティをnewTitle合成すると-newTitle、というメソッドが生成されるため、警告/エラーが発生します。-newTitlenewTitleプロパティのゲッターメソッドであると想定されていますが、命名規則でnewは、名前が始まるメソッドは呼び出し元が所有するオブジェクトを返すとされていますが、ゲッターメソッドの場合とは異なります。

これは次の方法で解決できます。

  1. そのプロパティの名前を変更する:

    @property (strong, nonatomic) NSString *theNewTitle;
  2. プロパティ名を保持し、特別なメソッド名のプレフィックスのいずれかで始まらないゲッター名を指定します。

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
  3. プロパティ名とゲッター名の両方を保持し、ゲッター名がで始まる場合でもnewnoneメソッドファミリーではなくメソッドファミリーに属していることをコンパイラーに伝えますnew

    #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、呼び出し元が所有するオブジェクトを返さないメソッドが呼び出されると、他の人がコードを読んで混乱する可能性があります。


参考までに、AppleはARCリリースノートへの移行を公開しました。

プロパティにnewまたはで始まる名前を付けることはできませんcopy

彼らの声明は正確ではないことが既に通知されています。原因はプロパティ名ではなく、getterメソッド名です。


2015年1月17日の編集:プロパティ名が特別なメソッドファミリープレフィックスのいずれかと一致する一般的なケースに対して、fix-itを含む上記のオプション3(を使用)を提案するClangへの最近のコミットに気づきましたobjc_method_family(none)。Xcodeは最終的にこの変更を組み込む可能性があります。


6
チャームマンのように働いた!! ありがとう!!! 将来の参考のために-「@property(strong、nonatomic、getter = theNewTitle)NSString * newTitle;」を使用しました
Noam

8
素晴らしい答え。「new」という接頭辞が付いた変数がありました。

私もこの問題を抱えており、私の時間を無駄にしています!あなたは本当に天才です〜ありがとうございます!
H Lai

NS_RETURNS_NOT_RETAINEDあなたも必要なものです。
DawnSong 2018

55

許可されないオブジェクト名

  • newButton
  • copyLabel
  • allocTitle

受け入れ可能なオブジェクト名

  • neueButton
  • mCopyLabel
  • _allocTitle

#arc#自動合成#xcode-4.6.1

**編集**

どうやらmutableCopyも使えないようです


1
「コピー」は今のところ使えないことに気づきました。
Rishab 2016

30

newで始まるメンバーの名前が警告をトリガーします。名前をeditedTitleに変更すると、警告が消えます。私はこれを確認するドキュメントを見つけることができませんでしたが、テストを通じて、「新しい」で始まるメンバー変数がコンパイラを悪化させることを確認できました。


8

ARCでは、プロパティ名に「New ...」を使用することはできません。ただし、ゲッター名を変更することで「newTitle」を使用できます。

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

6

Bavariousが提案したのは、あなたがやりたかったことではないようです。やりたいことは、インスタンス変数NewTitleを宣言してから、プロパティを合成することだけです。以前はインスタンス変数とプロパティを宣言する必要がありました。もういや。

今、これを行う正しい方法は次のとおりです:

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

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

プロパティのインスタンス変数newTitleが合成されます。インスタンス変数をプロパティと同じにしたくない- 間違いを犯しやすい

例:プロパティの宣言とアクセサの合成を参照してください


それはコンパイラのバージョンに依存します。この場合、clangの最近のバージョンは警告を発します。そのため、私の回答でコンパイラーのバージョンについて言及しました。

あなたは問題を解決したとは思わない。Xcode 9の場合、警告ではなくエラーです。NS_RETURNS_NOT_RETAINED必要なものです。
DawnSong 2018

4

CoreDataで属性に「new ...」を使用すると(正常にコンパイル)、「bad access」例外でランダムにクラッシュします。

クラッシュログはなく、「すべての例外ブレークポイント」で表示される行はまったく役に立ちません。


3

プロパティと同じ名前で手動でセッターを作成すると、この警告が削除されました。


Xcode 7.3では、これは役に立ちませんでした。プロパティ定義行にまだエラーが表示されます。
arlomedia 2016年

1

プロパティ名の前に「新しい」を使用する必要がある/できないという問題に加えて、もう1つ言いましょう。一般的に、名前の前に「新しい」を使用しないようにします。「新品」は時間に依存します。現在それはあなたにとって新しいですが、しばらくしてあなたはおそらく何か新しいものを再び実装したいと思うでしょう。したがって、名前に「新しい」を使用することは常に悪いことです。このように考えてみてください。プログラミングの世界では、「新しい」は常に何かを作成しています。つまり、何かの新しいインスタンスです。

別のタイトルを割り当てたい場合は、現在の名前をプロパティtitleReplacementにします。

もう1つ: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行にあります。
Noam
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.