1

Cocoa プロジェクト (Xcode) に 2 つのクラスがあります。1 つ目は AppDelegate クラスで、2 つ目は Book クラスです。

私の Book クラスでは、本の章である @interface に整数プロパティを設定しました。その @implementation では、オブジェクト (例: Book *firstBook = [[Book alloc]init]) を作成し、それらのプロパティを設定しました (Book.m ファイル内)。これらは私のデータであり、変更されません。

私のアプリデリゲートには、ユーザーがインターフェイスアイテムから選択したものを取得し、選択したアイテムのタイトルを取得するメソッドがあり、その名前は Book.m. 次に、 for ループが実行されて popUpButton のメニュー項目が作成されるため、ユーザーはジャンプ先の章を選択できます。

私が今見ている問題は、 for ループを実行してメニュー項目を作成しようとすると、制限量のループが必要になることです。その制限量は、selectedObjectByUser のチャプター プロパティ (Book.m にリストされています) に基づいています。どうすればアクセスできますか。

このメソッド内(AppDelegate.hの下)でオブジェクトを作成すると機能するため、これら2つを接続できれば機能すると確信していますが、スペースがかかりすぎて頻繁に変更されるという問題があります。

4

1 に答える 1

3

状況はよくわかりませんが、まずサンプル コードを見てみましょう。

//// Book.h
@interface Book : NSObject

@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *author;
@property (nonatomic, assign) NSInteger numberOfPages;

- (id)initWithTitle:(NSString *)aTitle andAuthor:(NSString *)anAuthor;

@end


//// Book.m
@implementation Book

- (id)initWithTitle:(NSString *)aTitle andAuthor:(NSString *)anAuthor {
    if ( self = [super init] ) {
        self.title = aTitle;
        self.author = anAuthor;
    }
    return self;
}

- (void)dealloc {
    self.title = nil;
    self.author = nil;
    [super dealloc];
}

@end

このように、クラスを確立し、タイトルと作成者 (どちらも NSString) と numberOfPages (整数) の 3 つのプロパティを提供します。クラス内では、 などを呼び出してこれらの値を操作できますself.propertyName = value

これはすべて順調ですが、実際に何が起こっているのでしょうか? ヘッダーをもう少し更新しましょう。

//// Book.h
@interface Book : NSObject {
@private
    NSString *_title;
    NSString *_author;
    NSInteger _numberOfPages;
}

@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSString *author;
@property (nonatomic, assign) NSInteger numberOfPages;

- (id)initWithTitle:(NSString *)aTitle andAuthor:(NSString *)anAuthor;

@end

これで、コンパイラーが通常は構文を介して推論する何かを明示的に定義しただけ@propertyです。これらの新しい追加は、インスタンス変数または ivar と呼ばれるものであり、プロパティに割り当てる値が実際に格納される場所です。

ただし、メモリ管理に 100% 慣れていない場合、ivar を操作するのは危険です。ARC を使用している場合でも、その管理がどのように機能するかを理解する必要があります。

これらのプロパティが実際にデータを格納する場所を明らかにしましたが、その@private仕事はどうですか? それは何ですか?@private何かの「アクセシビリティ範囲」を示すのに役立つキーワードのファミリーの一部です。このファミリの他の 2 つのキーワードは@protectedとですが、2 番目の 2 つのキーワード@publicの使用は、珍しいことではないにしてもまれです。これらのキーワードは、アクセスが許可されている場所を示す責任があります。それらの簡単な定義を次に示します。

  • @publicオブジェクト自体の外であっても、どこからでも自由にアクセスできます。しかし、それ自体のクラスの外部からインスタンス変数に直接アクセスすることは、Cocoa 開発の世界では一般に非常に悪い習慣と見なされているため、その方法についてほとんど見つけることができません。

  • @protectedクラスとそのサブクラス内で自由にアクセスできます。クラス/オブジェクトの外からはアクセスできません。

  • @privateクラス内では自由にアクセスできますが、他の場所ではアクセスできません。クラス/オブジェクトの外部またはそのサブクラスでさえもアクセスできません。

プロパティの背後にあるストレージを実際に駆動しているものについて説明したのでBookAppDelegate.

//// AppDelegate.m
@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    Book *myBook = [[Book alloc] initWithTitle:@"pending title" andAuthor:@"Foo Bar"];

    myBook.title = @"My Cool Book";

    NSLog(@"%@ by %@", myBook.title, myBook.author);

    [myBook release];
}

@end

ここでは、新しい Book オブジェクトを作成します。より専門的に言えば、myBookの型で呼び出される変数を定義しBook、インスタンス化します。-initWithTitle:andAuthor:ここでは、最初のタイトルと著者が必要であることを Book オブジェクトに伝えるために、以前に作成したメソッドを使用しています。

この行に続いて、もう少し興味深いものにたどり着きます。myBook.title = @"My Cool Book";Book.m で似たようなことがあったことを思い出すかもしれませんself.title = aTitle。それで、ここで何が起こっているのですか?以前のように、self ではなく myBook を使用するようになったのはなぜですか? その理由は、自分自身が実際に何であるかのためです。

selfObjective-C ランタイムによって提供されるキーワードであり、現在のオブジェクトを参照します。したがって、Book.m 内にコードを記述すると、self は現在の Book オブジェクトを参照します。AppDelegate.m 内で self を使用すると、AppDelegate を参照します。したがって、以前のコードでは、 myBook オブジェクトが特定の Book オブジェクトを参照しているように、self は現在の Book オブジェクトを参照していました。それらは本質的に互いに同等です(正確ではありませんが、それは別の議論の領域です)。

これは、Book.m 内で self を使用する場合と同様に、Book またはメソッド内の任意のプロパティに myBook 変数を介してアクセスできることを意味します。だから私たちもできる

myBook.title = @"My Book";
myBook.author = @"Baz Quux";
myBook.numberOfPages = 100;

これが役に立てば幸いです(そして、あなたの質問に答えました。そうでない場合は、プロパティとインスタンス変数についてもっと知りたい人への参照として役立つかもしれません)

于 2013-02-09T09:16:36.370 に答える