访问类别中的专用变量会导致链接器错误 [英] Accessing private variable in Category results in linker error
问题描述
编辑:我不会这样做,我现在知道这可能是多么危险。但是,这个问题纯粹是为了学术目的。
I'm not going to do this, I now realize how dangerous this can be. But, the question stays for purely academic purposes.
我试图在NSCollectionView上实现一个类别,让我访问私有变量_displayedItems。我需要能够在我的子类中访问它。所以,我创建了以下类别:
I'm trying to implement a category on NSCollectionView that will let me access the private variable _displayedItems. I need to be able to access it in my subclass. So, I've created the following category:
@interface NSCollectionView (displayedItems)
- (NSMutableArray *)displayedItems;
@end
@implementation NSCollectionView (displayedItems)
- (NSMutableArray *)displayedItems
{
return _displayedItems;
}
@end
...它应该工作完美。但是,当我尝试编译这个,链接器给我以下错误:
...which seems like it should work perfectly. However, when I try to compile this, the linker gives me the following error:
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。有没有人知道如何解决这个问题?
I know for a fact that _displayedItems exists in NSCollectionView, I've looked at the interface and also printed it's contents using gdb. Does anyone know of a way to fix this?
提前感谢!
比利
Thanks in advance!
Billy
推荐答案
_displayedItems
是一个私人的ivar,所以你不应该访问它,即使从一个类别。
_displayedItems
is a private ivar, so you shouldn't access it, even from a category.
也就是说,您应该尝试使用
That said, you should try compiling the same code with
gcc -arch i386
和
gcc -arch x86_64
并看到差异。在32位模式下,您看不到错误。这表明情况是多么脆弱。你真的不应该。
and see the difference. In the 32 bit mode you don't see the error. This shows how fragile the situation is. You really shouldn't.
也就是说,有一种方法可以通过滥用KVC获得该ivar:
That said, there's a way to get that ivar by abusing KVC:
@implementation NSCollectionView (displayedItems)
- (NSMutableArray *)myDisplayedItems
{
return [self valueForKey:@"displayedItems"];
}
@end
请注意将您的方法命名为 displayedItems
。这将使一个无限循环,因为KVC机制会发现你的方法早于ivar。请参见此处。
Note that you shouldn't name your method just as displayedItems
. That would make an infinite loop, because the KVC machinery would find your method earlier than the ivar. See here.
或者您可以使用Objective-C运行时函数访问任何隐藏的ivar。这也很有趣。
Or you can access any hidden ivar using Objective-C runtime functions. That's also fun.
但是,让我再说一遍。有一个很大的区别,知道你可以做一件事,做这个事情的真实。想想任何可怕的罪行。并自己这样做。
However, let me say again. There's a big difference in knowing you can do one thing and doing that thing for real. Just think of any hideous crime. and doing that by yourself.
这篇关于访问类别中的专用变量会导致链接器错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!