2010-12-13 3 views
10

編集:私はこれをやろうとはしません。しかし、この質問は純粋に学問的な目的のためにとどまります。カテゴリ内のプライベート変数にアクセスすると、リンカーエラーが発生する

プライベート変数_displayedItemsにアクセスできるようにするカテゴリをNSCollectionViewに実装しようとしています。私は私のサブクラスでそれにアクセスできる必要があります。

@interface NSCollectionView (displayedItems) 

- (NSMutableArray *)displayedItems; 

@end 


@implementation NSCollectionView (displayedItems) 

- (NSMutableArray *)displayedItems 
{ 
    return _displayedItems; 
} 

@end 

...それは完璧に動作するはずのように思える:だから、私は、次のカテゴリを作成しました。私はこれをコンパイルしようとすると、しかし、リンカは私に次のエラーを与える:

Undefined symbols: 
    "_OBJC_IVAR_$_NSCollectionView._displayedItems", referenced from: 
     -[NSCollectionView(displayedItems) displayedItems] in NSCollectionView+displayedItems.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

私は_displayedItemsがNSCollectionViewに存在するという事実のために、私はインターフェイスを見ても、それはGDBを使用して内容だ印刷されてきました知っています。誰でもこれを解決する方法を知っていますか?

ありがとうございます!
ビリー

+0

これは最高の回答であることがわかりました。簡単、簡単、安全: http:// stackoverflowcom/questions/16678463/access-a-super-class-exposed-not-exposed-exposed- –

答えて

12

_displayedItemsはプライベートなivarですので、カテゴリーからもアクセスしないでください。あなたは

gcc -arch i386 

gcc -arch x86_64 

との違いを参照して同じコードをコンパイルしてみてください、と述べ

。 32ビットモードでは、エラーは表示されません。これは状況がどれほど脆弱かを示します。あなたは本当にすべきではありません。

KVCを悪用することにより、そのIVARを取得する方法があります、言った:あなたはちょうどdisplayedItemsとして、あなたの方法に名前を付けるべきではありません

@implementation NSCollectionView (displayedItems) 

- (NSMutableArray *)myDisplayedItems 
{ 
    return [self valueForKey:@"displayedItems"]; 
} 

@end 

注意。それはKVC機械があなたの方法をivarよりも早く見つけられるので、無限ループを作ります。 hereを参照してください。

Objective-Cランタイム関数を使用して、隠しivarにアクセスできます。それも楽しいです。

しかし、もう一度言います。あなたが一つのことをすることができ、そのことを実際に行うことができるということに大きな違いがあります。どんな恐ろしい犯罪も考えてください。あなた自身でそれをやっています。

しないでください!!!!!

+0

申し訳ありませんが、私はそれを、悪い考えを得る。 :) とにかくありがとう! – vilhalmer

+1

私は「しないでください」を先頭に移動します。 :)あなたがフレームワーククラスの内部状態を把握し始めるなら、時間の経過とともにクラッシュや不思議な失敗に驚かれることは間違いありません。 – bbum

+0

@bbumは、他の答えで提案されている 'object_getInstanceVariable'では比較的無害ですか? –

5

あなたは本当にないはずですが、構造体のメンバへのポインタのようなアクセスを:私はあなたが認識していると確信しているよう

-(NSMutableArray *)displayedItems { 
    return self->_displayedItems; 
} 

これは、行うには壊れやすいものですしかし;)

UPDATE:あなたは上記したので、実行時に落下しようとすると、動作しません:

-(NSMutableArray *)displayedItems { 
     NSMutableArray *displayedItems; 
     object_getInstanceVariable(self, "_displayedItems", (void *)&displayedItems); 
     return displayedItems; 
} 

(テスト済み、動作します)

+0

これはどちらもうまくいかず、同じエラーが発生します。しかし、提案してくれてありがとう! – vilhalmer

+0

うーん、ああ!私の更新を参照してください。 – d11wtq

+3

それは技術的に正解ですが、倫理的に正しい答えはありません:p – Yuji

関連する問題