0

myPropertyNameクラスで definedというプロパティがあるとしますMyClassName。この記事では、手動のメモリ管理を使用しています。

MyClassName.h

#import <UIKit/UIKit.h>
@interface MyClassName : NSObject {
    @private
        NSObject* myPropertyName;
    @public
}
@property (nonatomic, retain) NSObject* myPropertyName;
// Some methods prototypes are here
@end

MyClassName.m

#import "MyClassName.h"
@implementation MyClassName
@synthesize myPropertyName;
// Some methods are here
@end

myPropertyName宣言の場所、インスタンス変数との違いなどの使い方に戸惑います。たとえば、-(void)initmy class のカスタマイズされたメソッドなど、初期化コードのこれら 3 つのステートメントの違いは何ですかmyClassName

  1. self.myPropertyName = [[[NSObject alloc] init] autorelease];

    これはセッターを呼び出しmyPropertyNameていますが、セッターで使用されているインスタンス変数の名前が何であるかはわかりmyPropertyNameません. )?myPropertyName_myPropertyName

  2. myPropertyName = [[NSObject alloc] init];

    これはプロパティのインスタンス変数を初期化しますmyPropertyNameか? を持っていない場合@synthesize myPropertyName = _myPropertyName;、プロパティのデフォルトのインスタンス変数は であると言われているため、間違っているでしょうか_myPropertyName

  3. _myPropertyName = [[NSObject alloc] init];

    andを使用しても_myPropertyName、プロパティのインスタンス変数としてまだ宣言されていますか?myPropertyName@synthesize myPropertyName;@private NSObject* myPropertyName;

私の理解では、プロパティは単なる名前 ( などmyPropertyName) であり、値の割り当てなど、コード内の実際の操作で使用されるようにカプセル化されたインスタンス変数が必要です。

4

2 に答える 2

2

まず、nhgrif でリンクされているプロパティに関する Apple のドキュメントを読むことを強くお勧めします。ただし、ドキュメントが少し分厚い読み物になる可能性があることは理解しています (ただし、Apple のものはそれほど悪くはありません)。そこで、ここでプロパティの概要を簡単に説明します。

私は例が好きなので、あなたの 2 つのクラスをもう少し最新の形に書き直します。

MyClassName.h

#import <UIKit/UIKit.h>
@interface MyClassName : NSObject

@property (nonatomic, strong) NSObject *myPropertyName;
// method prototypes here
@end

MyClassName.m

#import "MyClassName.h"
@implementation MyClassName
// some methods here
@end

クラスには、 typeMyClassNameという名前のプロパティが追加されました。この場合、コンパイラは「無料」で多くの作業を行います。具体的には、バッキング変数を生成し、 のセッターとゲッターも生成します。私が 2 つのファイルを書き直して、そのようなものも含めて私がコンパイラーのふりをするとしたら、次のようになります。myPropertyNameNSObject *myPropertyName

MyClassName.h

#import <UIKit/UIKit.h>
@interface MyClassName : NSObject {
    NSObject *_myPropertyName;
}

@property (nonatomic, strong) NSObject *myPropertyName;

- (void)setMyPropertyName:(NSObject *)obj;
- (NSObject *)myPropertyName;

@end

MyClassName.m

#import "MyClassName.h"
@implementation MyClassName

- (void)setMyPropertyName:(NSObject *)obj
{
    _myPropertyName = obj;
}

- (NSObject *)myPropertyName
{
    return _myPropertyName;
}

@end

繰り返しますが、これはすべて「無料」で行われています。内部で何が行われているかを示しているだけです。それでは、番号付きの質問に答えてください。

  1. self.myPropertyName = [[[NSObject alloc] init] autorelease];

    まず第一に、おそらく自動参照カウント (ARC) を使用しているはずです。その場合、電話をかけることはできませんautorelease。その部分を無視して、これはうまくいきます。を除くとautorelease、これは次とまったく同じです。

    [self setMyPropertyName:[[NSObject alloc] init]];

    上記の 2 番目の.mファイルを見ると、基本的に次のように変換されます。

    `_myPropertyName = [[NSObject alloc] init];

  2. myPropertyName = [[NSObject alloc] init];

    myPropertyName書かれているように、このクラスで呼び出される変数がないため、このコードはコンパイラ エラーを返します。プロパティの基になる (または「バッキング」する) インスタンス変数に本当にアクセスしたい場合はmyPropertyName、実際の名前を使用して次のようにできます。

    _myPropertyName = [[NSObject alloc] init]; // note the underscore

    しかし、ほとんどの場合、ポイント 1 のようにセッターを使用することをお勧めします。これは、副作用、キー値コーディング、およびその他の優れた機能を考慮に入れるためです。

  3. _myPropertyName = [[NSObject alloc] init];

    おー。さて、あなたはそれを手に入れました。ポイント2を参照してください。

あなたは次のように述べました:

myPropertyName宣言の場所、インスタンス変数との違いなどの使い方に戸惑います。たとえば、-(void)initmy class のカスタマイズされたメソッドなど、初期化コードのこれら 3 つのステートメントの違いは何ですかmyClassName

明確にされていない場合、プロパティは抽象的な概念のようなものです。そのデータは通常のインスタンス変数に格納され、通常はコンパイラによって割り当てられます。そのアクセスは通常、重要な例外を除いて、setter と getter に制限する必要があります。この答えを短くするために、それ以上の詳細には触れません。

もう1つ: nhgrif が述べたように、@synthesizeキーワードを使用する必要はもうありません。これは、コンパイラによって暗黙的に理解されます。

これについて不明な点がある場合は、コメントを投稿するか、ドキュメントを読んでください。

于 2013-10-29T03:34:33.317 に答える
1

この例を見てみましょう:

@property NSString *fullName;

実装でセッターとゲッターをオーバーライドし、これらのセッターとゲッターでインスタンス変数を使用しない場合、インスタンス変数fullNameは作成されません。例えば:

- (NSString *)fullName
{
    return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

- (void)setFullName:(NSString *)fullName
{
    //logic to split fullName into two strings
    //self.firstName = etc
    //self.lastName = etc.
}

この例では、fullNamecreated のインスタンス変数はありません。

これはAppleの公式ドキュメントによると

ただし、setter と getter の両方をオーバーライドしないと、インスタンス変数が作成されます。

補足として、プロパティを宣言すると、 (変数を使用せずに) をreadonlyオーバーライドするだけで が作成されなくなります。同様に、プロパティを宣言して、.getterivarwriteonlysetter

于 2013-10-29T01:49:59.530 に答える