2010-12-13 50 views
10

EDIT: Tôi sẽ không làm điều này, bây giờ tôi nhận ra mức độ nguy hiểm của điều này. Nhưng, câu hỏi vẫn ở lại cho mục đích học tập thuần túy.Truy cập biến riêng tư trong Kết quả danh mục trong lỗi trình liên kết

Tôi đang cố triển khai danh mục trên NSCollectionView cho phép tôi truy cập biến riêng _displayedItems. Tôi cần để có thể truy cập nó trong phân lớp của tôi. Vì vậy, tôi đã tạo danh mục sau:

@interface NSCollectionView (displayedItems) 

- (NSMutableArray *)displayedItems; 

@end 


@implementation NSCollectionView (displayedItems) 

- (NSMutableArray *)displayedItems 
{ 
    return _displayedItems; 
} 

@end 

... có vẻ như nó sẽ hoạt động hoàn hảo. Tuy nhiên, khi tôi cố gắng biên dịch này, mối liên kết mang lại cho tôi những lỗi sau:

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 

Tôi biết một thực tế rằng _displayedItems tồn tại trong NSCollectionView, tôi đã xem xét giao diện và cũng được in nội dung của nó sử dụng gdb. Có ai biết cách sửa lỗi này không?

Cảm ơn trước!
Billy

+0

Tôi thấy đây là câu trả lời hay nhất. Dễ dàng, đơn giản và an toàn: http: // stackoverflow.com/questions/16678463/truy cập-a-method-in-a-super-class-khi-nó-không-tiếp xúc –

Trả lời

12

_displayedItems là một thanh công cụ riêng tư, vì vậy bạn không nên truy cập vào nó, thậm chí từ danh mục.

Điều đó nói rằng, bạn nên cố gắng biên dịch mã cùng với

gcc -arch i386 

gcc -arch x86_64 

và thấy sự khác biệt. Ở chế độ 32 bit, bạn không thấy lỗi. Điều này cho thấy tình hình dễ vỡ như thế nào. Bạn thực sự không nên.

Điều đó nói rằng, có một cách để có được Ivar rằng bằng cách lạm dụng KVC:

@implementation NSCollectionView (displayedItems) 

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

@end 

Lưu ý rằng bạn không nên đặt tên phương pháp của bạn cũng giống như displayedItems. Điều đó sẽ tạo ra một vòng lặp vô hạn, bởi vì máy móc KVC sẽ tìm ra phương pháp của bạn sớm hơn so với ngà voi. Xem here.

Hoặc bạn có thể truy cập bất kỳ thanh công cụ ẩn nào bằng chức năng thời gian chạy Objective-C. Đó cũng là niềm vui.

Tuy nhiên, hãy để tôi nói lại. Có một sự khác biệt lớn trong việc biết bạn có thể làm một việc và làm điều đó thật. Chỉ cần nghĩ về bất kỳ tội ác ghê tởm nào. và làm điều đó một mình.

KHÔNG LÀM GÌ !!!!!

+0

Được rồi, tôi hiểu rồi, ý tưởng tồi. :) Dù sao cũng cảm ơn bạn! – vilhalmer

+1

Tôi muốn di chuyển "không làm điều đó" lên đầu. :) Nếu bạn bắt đầu mucking về với trạng thái nội bộ của các lớp khung, bạn chắc chắn sẽ ngạc nhiên bởi các sự cố và thất bại bí ẩn theo thời gian. – bbum

+0

@bbum không phải là 'object_getInstanceVariable' được đề xuất trong câu trả lời khác tương đối vô hại? –

5

Bạn không nên thực sự, nhưng việc tiếp cận nó như một con trỏ đến một thành viên của một struct:

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

Đây là một điều mong manh để làm, như tôi chắc chắn rằng bạn đang nhận thức Tuy nhiên;)

UPDATE: Vì bạn đã đề cập ở trên không hoạt động, hãy thử thả xuống để thời gian chạy:

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

(Tested, hoạt động)

+0

Điều này không có tác dụng, nó cung cấp cho một lỗi giống hệt nhau. Nhờ đề nghị mặc dù! – vilhalmer

+0

Hmm, d'oh! Xem cập nhật của tôi. – d11wtq

+3

Đó là câu trả lời đúng về mặt kỹ thuật, nhưng không phải là câu trả lời đúng về mặt đạo đức: p – Yuji

Các vấn đề liên quan