0

AとBの2つのクラスがあるとします。Aはシングルトンです。BでAを宣言しているので、Bのメソッドでシングルトン変数にアクセスできます。

次に、Bは別のクラス、たとえばクラスCのインスタンスを作成します。

C次に、別のクラス、たとえばクラスDのインスタンスを作成します。

私がする必要があるのは、クラスDのクラスBのインスタンスでメソッドを実行することです。それが、私を悩ませています。

私の最初の考えは、クラスbのインスタンスへの参照を私のシングルトン(クラスA)に置くことでした...

sharedInstance.classBReference = self;

..次に、クラスDでシングルトンを宣言し、クラスDインスタンスでこのようなものを使用します。

[sharedInstance.classBInstance classBInstanceMethod];

しかしもちろん、私がやったとたんに。

classB *classBReference;

私のシングルトンのヘッダーには、ここで読んだ「不明なタイプ」が含まれているので、代わりに

@class classB;

@interfaceの上に、そして私は宣言することができました...

classB *classBReference;

不明なタイプのエラーはありませんが、クラスBのinitメソッドでは、これは...

sharedInstance.classBReference = self;

それでもタイプのエラーが発生します

「タイプ「クラスA*」(シングルトン)のオブジェクトにプロパティclassBReferenceが見つかりません。これは、ivar classBReferenceにアクセスすることを意味しましたか?」

そして、なぜそれがそれをしているのか分かりません、解決策は何ですか?または私がやろうとしていることをするためのより良い方法はありますか?

4

3 に答える 3

1

点と矢印

「ドット表記」は、Objective-Cに最近追加されたものであり、アクセサに簡略表記を提供します。オブジェクト(または構造体!)へのポインタがある場合、そのインスタンス変数にアクセスすることはできませんが、。を使用する.だけ->です。

あなたのライン

sharedInstance.classBReference = self;

とまったく同じです

[sharedInstance setClassBReference:self];

問題は、そのような方法がないことです-setClassBReference:。インスタンス変数を設定するには、代わりに次のように記述する必要があります。

sharedInstance->classBReference = self;

@保護された変数

これでラインを切り替えた後、(まだ行っていない場合は@public)エラーが表示される場合があります

インスタンス変数' classBReference'はプライベートです

この場合、であると宣言されるclassAようにインターフェースを変更する必要があります。のインスタンス変数のリストは次のようになります。classBReference@publicclassA

@interface classA : NSObject
{
//@protected
//(The @protected keyword is optional when at the beginning of the list; instance
//variables are protected by default, which is why you're needing to declare your
//instance variable classBReference to be @public (since classB is not a subclass
//of classA and consequently cannot access its protected instance variables).
    //....
    //some protected instance variables
    //....
@private
    //....
    //some private instance variables
    //....
@public
    //....
    //some public instance variables
    classB *classBReference;
    //....
@protected
    //....
    //some more protected instance variables
    //Note that @protected is not optional in order to make the instance variables
    //here be protected since they are declared subsequent to the prior @public.
    //....
}
//....
@end

@propertiesの使用

classBReferenceの場合

そうは言っても、一般的にインスタンス変数ではなくアクセサーを使用する方が良い方法と広く見なされています。これを行うには、classAインターフェイスにプロパティを追加する必要があります。

@interface classA : NSObject
{
    classB *classBReference;
}
@property classB *classBReference;
@end

classBReference 次のように、プロパティを合成して、の実装でclassBReference インスタンス変数にアクセスします。classA

@implementation classB

@synthesize classBReference = classBReference;

一般的な設定

インスタンス変数と同じ名前のプロパティの両方があるため、これ@synthesizeはやや不明確です。いくつかの説明が必要です。一般に、クラス(この例では " MyObject")では@interface、インスタンス変数(myVariableこの例では "")とプロパティ(この例では"")を宣言しますmyProperty

@interface MyObject : NSObject
{
    SomeObject *myVariable;
}
@property SomeObject *myProperty;
@end

クラスの@implementation1つには行があります

@synthesize myProperty = myVariable.

このコードの結果は、インスタンスが与えられた場合です

MyObject *object = //...

クラスの、1つは書くことができます

SomeObject *someObject = //...
[object setMyProperty:someObject];

SomeObject *someOtherObject = [object myProperty];

-setMyProperty:のインスタンスを呼び出した結果は、メソッドに渡された引数(この場合MyObjectmyVariable)と等しく設定されsomeObjectます。同様に、-myPropertyのインスタンスをMyObject呼び出した結果myVariableが返されます。

それは私たちに何をもたらしますか?

@propertyandディレクティブがない@synthesizeと、メソッドを宣言する必要があります

- (void)setMyProperty:(SomeObject *)myProperty;
- (SomeObject *)myProperty;

手動で定義し、手動で定義します。

- (void)setMyProperty:(SomeObject *)myProperty
{
    myVariable = myProperty;
}

- (SomeObject *)myProperty
{
    return myVariable;
}

@propertyおよびは、この@synthesizeコードにいくつかの要約を提供します。さまざまなプロパティ属性を使用すると、生成されるコードの量がさらに有益になります。

:andディレクティブについてはさらに多くのことが言えます。まず、変数名を省略して記述できるだけでなく、の合成も完全に省略できます。この2つの場合、自動的に使用される変数名は異なります。 @property@synthesize@synthesize myProperty;myProperty

ドット表記についてもう少し

あなたの質問からのドット表記は、略語の別の層を提供します。書く必要はなく

[object setMyProperty:someObject];

あなたは今書くことができます

object.myProperty = someObject;

同様に、書く必要はありません

SomeObject *someOtherObject = [object myProperty];

あなたは今書くことができます

SomeObject *someOtherObject = object.myProperty;

これは単なる表記であることに注意することが重要です。object.myProperty「ちょっと」のように見えますが、「等しい」に設定すると単純な割り当てを行っていますが、そうsomeObjectではありません。特に、ラインを実行するとき

object.myProperty = someObject;

メソッド

- (void)setMyProperty:(SomeObject *)someObject

実行されます。このため、ドット 表記 いくつかの論争 対象 です 。これは便利ですが、コードが何をしているのかを覚えておくことが重要です。

于 2012-10-30T03:08:39.223 に答える
0

エラーメッセージはあなたに答えを教えてくれます。classBReferenceプロパティとして定義するかclassBReference、ivarとして使用する必要があります。

于 2012-10-30T03:01:56.240 に答える
0

グローバル変数(別名シングルトン)を回避することで、混乱が少なくなるように思えます。を作成するときCへの参照を与えます。を作成するときへの参照を与えます。BBCDBCD

保持サイクルを回避する必要がある場合は、 (デプロイメントターゲットがiOS 5.0以上の場合)または(デプロイメントターゲットがiOS 5.0より前の場合)のBいずれかへの逆参照を作成します。weakunsafe_unretained

于 2012-10-30T03:08:26.153 に答える