あなたは尋ねました:
他のクラスから値を取得する別の方法はありますか?
簡単に言えば、「ゲッター」を使用するのが、別のクラスから値を取得する慣習的な方法です。しかし、あなたの問題を見て (問題を適切に診断するのに十分なソース コードがないことは認められています)、問題はインスタンス変数の使用にあると推測しています。しかし、それについては後で詳しく説明します。
まず、宣言されたプロパティとそのインスタンス変数、およびそれらのアクセサー メソッド (ゲッターとセッター)の適切な使用方法を見てみましょう。通常、これらのアクセサー メソッドを使用してプロパティを設定する必要があります。ただし、インスタンス変数のいずれかを使用して、クラス内から変数にアクセスできます (また、イニシャライザ メソッドと dealloc メソッドでアクセサ メソッドを使用しないでください)。[self customObject]
また、getter と setter を使用する場合は、メソッド呼び出し (" " など) を使用するか、ドット表記 (" " など)を使用するかを選択できますself.customObject
。
例を見てみましょう。あなたがいくつかの単純なものを持っていると仮定しましょうCustomClass
:
@interface CustomClass : NSObject
{
// you don't need to declare the instance variable
//int _boxSpacing;
}
@property (nonatomic) int boxSpacing;
@end
@implementation CustomClass
// In Xcode 4.4 and later, the synthesize statement is optional, and if you
// omit it, it will synthesize the instance variable like this, with the
// leading underscore. While you don't need to use an underscore in your
// instance variable, it has become convention in iOS development and it's
// a good technique to minimize chances that you accidentally use the instance
// variable when you actual intended to use the property's accessor methods
// (the getter and setter).
@synthesize boxSpacing = _boxSpacing;
@end
CustomClass
ここで、たとえばビュー コントローラー内からこれを使用すると仮定しましょう。したがって、最初に this のインスタンスを宣言しますCustomClass
。
@interface MyViewController : UIViewController
{
// you do not need this instance variable declaration
// the @synthesize statement will take care of this for you
// CustomClass *_customObject;
}
@property (nonatomic, strong) CustomClass *customObject;
@end
次に、View Controller 内からオブジェクトのvalue
プロパティを使用する方法を示しましょう。CustomClass
customObject
@implementation MyViewController
// Again, in Xcode 4.4 and later, the synthesize statement is optional, and if you
// omit it, it will synthesize the instance variable like this, with the
// leading underscore
@synthesize customObject = _customObject;
- (void)customClassTest
{
// initialize the object
self.customObject = [[CustomClass alloc] init];
// set the property
self.customObject.boxSpacing = 1;
// finally, let's demonstrate three ways to retrieve the value
NSLog(@"%d", self.customObject.boxSpacing);
NSLog(@"%d", [[self customObject] boxSpacing]);
NSLog(@"%d", _customObject.boxSpacing);
// while we're at it, let's demonstrate other ways to set the property
_customObject.boxSpacing = 2;
// or
[[self customObject] setBoxSpacing:3];
}
では、問題に戻りましょう。あなたは言う:
_customclass.variable と書きます。CustomClass は別のクラスで、変数はプロパティで、int 型です。そして、このクラスの変数の値を取得しますが、それを self.customclass.variable に変更すると、常に 0 になります。
@synthesize
わかりました、これはいくつかの異なる問題によって引き起こされる可能性がありますが、私が目にする最も一般的な問題は、明示的に宣言されたインスタンス変数と、ステートメントによって舞台裏で作成されたインスタンス変数との間の混乱です。これが、宣言されたプロパティのインスタンス変数を明示的に定義するのではなく、@synthesize
ステートメントで自動的に定義するように常にアドバイスする理由です。そうすれば、これから説明するような問題は発生しません。
次の無害な (ただし正しくない) 例を考えてみましょう。
@interface MyViewController : UIViewController
{
CustomClass *_customObject;
}
@property (nonatomic, strong) CustomClass *customObject;
@end
@implementation MyViewController
@synthesize customObject;
- (void)customClassTestError
{
// initialize the object
self.customObject = [[CustomClass alloc] init];
// this works
self.customObject.boxSpacing = 1;
// this doesn't!
_customObject.boxSpacing = 2;
// when it hits this statement, the value will still be 1!!!
NSLog(@"%d", self.customObject.boxSpacing);
}
問題が見えますか?アンダースコア を使用してインスタンス変数を宣言しましたが_customObject
、コンパイラが@synthesize
ステートメントにヒットすると、別のインスタンス変数が作成されました。今回は先頭のアンダースコア がありませんcustomObject
。したがって、明示的に宣言されたインスタンス変数は init/alloc を受け取っていないため、nil
それを使用しようとしても機能しません!
通常、逆の問題 (アンダースコアなしで明示的に宣言されたインスタンス変数と@synthesize
形式のステートメント@synthesize customObject = _customObject
) が見られますが、アイデアが得られることを願っています。
とにかく、これはあなたが説明する動作を引き起こす最も一般的な例です。これが起こっていない場合は、より広範なコード サンプルを提供してください。
しかし、問題がある場合は、CustomClass
オブジェクトのプロパティにアクセスする前に、オブジェクト自体の値を確認することをお勧めします。プロパティを使用する前に、クラス オブジェクト自体が適切に初期化されていることを確認してください (上記の理由によるか、その他の初期化の問題のためか)。NSLog(@"CustomClass object = %@", customObject);
またはのようなことができますNSAssert(customObject, @"Object not properly initialized");
。