web-dev-qa-db-ja.com

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

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

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

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

.m

@synthesize newTitle;

誰も私がこれを修正する方法の手がかりを持っていますか?ありがとう!!

280
Noam

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

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

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

これを解決するには:

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

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

    @property (strong, nonatomic, getter=theNewTitle) NSString *newTitle;
    
  3. プロパティ名とゲッター名の両方を保持し、ゲッター名がnewで始まっていても、noneメソッドファミリーではなく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で始まる名前を付けることはできません。

声明は正確ではないことが既に通知されています。犯人はゲッターメソッド名であり、プロパティ名ではありません。


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

601
user557219

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

  • newButton
  • copyLabel
  • allocTitle

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

  • neueButton
  • mCopyLabel
  • _allocTitle

#arc#auto-synthesized#xcode-4.6.1

**編集**

どうやらmutableCopyも使用できないようです。

50
Jacksonkr

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

29
Michael

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

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

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

今、私はこれを行う正しい方法は次のとおりであると信じています:

.h

@interface ViewController : UIViewController

@property (nonatomic, strong) NSString *newTitle;

.m

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

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

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

5
aquraishi

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

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

3
las

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

2
Serge Rykovski

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

あなたの場合、異なるタイトルを割り当て、現在の名前をプロパティtitleReplacementに割り当てたい場合。

もう1つ:setSomethingやgetSomethingなど、最初に動詞を使用して関数とメソッドに名前を付けてください。ただし、プロパティでは、まずheightMinimum、heightMaximumなどのようにオブジェクトに名前を付けてください。コーディング中にインスペクターを使用するときは、常にオブジェクトを探します。やってみよう。 ;-)

0

NS_RETURNS_NOT_RETAINEDは、命名の問題を解決するために使用されます。

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

次のように definition を見つけることができます。

#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))

「ns_returns_not_retained」属性は、「ns_returns_retained」の補足です。関数またはメソッドがCocoaの規則に従って、保持されているCocoaオブジェクトを返すように見える場合、この属性を使用して、返されるオブジェクト参照を呼び出し側に返される「所有」参照と見なすべきでないことを示すことができます。 Foundationフレームワークは、NS_RETURNS_NOT_RETAINEDマクロを定義します。これは、以下に示すものと機能的に同等です。

添付 詳細 こちら。

0
DawnSong