2010-12-13 14 views
10

EDIT: I nie zamierzam tego robić, ja sobie teraz sprawę, jak niebezpieczna może to być. Ale pytanie pozostaje wyłącznie do celów akademickich.Dostęp do zmiennej prywatnej w wynikach Kategoria omyłkowo łącznikowej

Próbuję zaimplementować kategorię na NSCollectionView, która pozwoli mi uzyskać dostęp do prywatnej zmiennej _displayedItems. Muszę mieć dostęp do niego w mojej podklasie. Tak więc utworzyłem następującą kategorię:

@interface NSCollectionView (displayedItems) 

- (NSMutableArray *)displayedItems; 

@end 


@implementation NSCollectionView (displayedItems) 

- (NSMutableArray *)displayedItems 
{ 
    return _displayedItems; 
} 

@end 

... która wygląda na to, że powinna doskonale działać. Jednak, gdy próbuję skompilować ten łącznik daje mi następujący błąd:

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 

wiem na pewno, że _displayedItems istnieje w NSCollectionView, szukałem w interfejsie, a także drukowane to zawartość używając gdb. Czy ktoś wie o sposobie rozwiązania tego problemu?

Z góry dziękuję!
Billy

+0

Znalazłem to być najlepszym rozwiązaniem. Łatwy, prosty i bezpieczny: http: // stackoverflow.com/questions/16678463/accessing-a-method-in-a-super-class-when-it-not-not-exposed –

Odpowiedz

12

_displayedItems jest prywatnym ivar, więc nie powinieneś mieć do niego dostępu, nawet z kategorii.

To powiedziawszy, należy spróbować kompilacji tego samego kodu z

gcc -arch i386 

i

gcc -arch x86_64 

i zobaczyć różnicę. W trybie 32-bitowym nie widzisz błędu. To pokazuje, jak krucha jest ta sytuacja. Naprawdę nie powinieneś.

powiedział, że istnieje sposób, aby ta ivar nadużywając KVC:

@implementation NSCollectionView (displayedItems) 

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

@end 

pamiętać, że nie należy wymienić metodę jak displayedItems. To spowodowałoby nieskończoną pętlę, ponieważ maszyna KVC znajdzie twoją metodę wcześniej niż ivar. Zobacz here.

Lub możesz uzyskać dostęp do wszelkich ukrytych ivar przy użyciu funkcji wykonawczych C-C. To też jest fajne.

Jednak, pozwól mi powtórzyć. Różnica polega na tym, że wiesz, że możesz zrobić jedną rzecz i zrobić to naprawdę. Wystarczy pomyśleć o jakiejkolwiek ohydnej zbrodni. i robiąc to samemu.

nie rób tego !!!!!

+0

Dobra, rozumiem, zły pomysł. :) I tak dzięki! – vilhalmer

+1

Przesunąłbym "nie rób tego" na górę. :) Jeśli zaczniesz się grzebać z wewnętrznym stanem klas frameworku, z pewnością zaskoczą Cię awarie i tajemnicze awarie z biegiem czasu. – bbum

+0

@bbum nie jest "niewidoczną" zmienną "object_getInstanceVariable" zasugerowaną w drugiej odpowiedzi? –

5

Nie należy naprawdę, ale dostęp do niego podobny wskaźnik do członka struct:

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

Jest kruchą rzeczą do zrobienia, jak jestem pewien, że jesteś świadomy jednak;)

UPDATE: Skoro już wspomniano wyżej, nie działa, spróbuj spada w dół do wykonywania:

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

(Testowany, działa)

+0

To też nie działa, daje identyczny błąd. Dzięki za sugestię! – vilhalmer

+0

Hmm, d'oh! Zobacz moją aktualizację. – d11wtq

+3

To jest poprawna pod względem technicznym odpowiedź, ale nie jest to poprawna moralnie odpowiedź: p – Yuji