3

次の拡張機能を含むサードパーティのクラスを使用しています。

@interface BaseClass ()
{
   int privateMember;
}
@end

私は自分のサブクラスを作成しました:

  @interface SubClass : BaseClass {
  }
  @end

サブクラスのprivateMemberにアクセスする方法はありますか?


編集:実際のコード

GPUImageMovie.m :(基本クラス)

@interface GPUImageMovie ()
{
    BOOL audioEncodingIsFinished, videoEncodingIsFinished;
    GPUImageMovieWriter *synchronizedMovieWriter;
    CVOpenGLESTextureCacheRef coreVideoTextureCache;
    AVAssetReader *reader;
}

MultiTrackGPUImageMovie.h(サブクラス)

@interface MultiTrackGPUImageMovie : GPUImageMovie {
}
...
@end

MultiTrackGPUImageMovie.m(サブクラス)

 - (void)processMovieFrame:(CMSampleBufferRef)movieSampleBuffer forTarget:(int)targetToSendIdx {
 ...
 CVReturn err = CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,       coreVideoTextureCache, movieFrame, NULL, GL_TEXTURE_2D, GL_RGBA, bufferWidth, bufferHeight,   GL_BGRA, GL_UNSIGNED_BYTE, 0, &texture);
 ...
}

エラーを与える宣言されていない識別子の使用'coreVideoTextureCache'

4

2 に答える 2

5

これは、「プライベート」メンバーがどのように宣言されているかによって異なります。その前にキーワードがなかった場合@private、つまりそれは本当にだった

@interface BaseClass ()
{
    int privateMember;
}
@end

ではなく

@interface BaseClass ()
{
    @private
    int privateMember;
}
@end

次に、その名前を使用するだけで、このインスタンス変数を簡単に参照できます。インスタンス変数のデフォルトのアクセススコープは保護されています。つまり、クラスの外部からはアクセスできませんが、サブクラスからはアクセスできます。

ただし、として宣言されてprivateいる場合は、ランタイム関数を使用してフォールバックする必要があります。サブクラスで、次のメソッドを宣言して実装します。

- (void *)pointerForIvarWithName:(NSString *)name
{
    Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
    return ((char *)self) + ivar_getOffset(ivar);
}

次に、次のように使用します。

int ivarPtr;
ivarPtr = *(int *)[self pointerForIvarWithName:@"privateMember"];

編集:アクセスしようとしているメンバーはクラス拡張子にあり、ヘッダーファイルでは公開されていないようです。この場合、2番目の解決策のみを選択できます(ただし、そうすることはお勧めしません)。

于 2012-08-04T18:39:02.897 に答える
0

私の場合、クラス拡張子が.mファイルにある場合、受け入れられた答えのように、サブクラスのクラス拡張子からデフォルトの@protectedivarを使用することは不可能です。

したがって、ランタイムAPIを使用せずにこの問題を解決する方法を次に示します(このような方法で使用しないでください)。


これらは、サブクラス`SubClassにも実装されています。宣言はサブクラスに表示されないため、これらにアクセスすることはできません。

サブクラスは、のクラス拡張子 @interface BaseClass ()にアクセスできませんBaseClass

2つのオプションがあります:

コピー

@interface BaseClass () {
    int privateMember;
}
@end

すべてのサブクラスに。はい、それはのファイル内のクラス拡張子です。BaseClass.mSubClass

また

クラス拡張子コード(上記のような)のみを.h含む、を含まないファイルを作成します。それをと.mにインポートします。BaseClassSubClass

于 2014-05-20T19:09:06.013 に答える