我正在尝试在NSCollectionView上实现一个允许我访问私有变量_displayedItems的类别。我需要能够在我的子类中访问它。所以,我创建了以下类别:
@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 :(得分:12)
_displayedItems
是私有的ivar,所以即使是从类别中也不应该访问它。
那就是说,你应该尝试使用
编译相同的代码gcc -arch i386
和
gcc -arch x86_64
并看到差异。在32位模式下,您没有看到错误。这表明情况是多么脆弱。你真的不应该。
那就是说,有一种方法可以通过滥用KVC来获得这种伊娃:
@implementation NSCollectionView (displayedItems)
- (NSMutableArray *)myDisplayedItems
{
return [self valueForKey:@"displayedItems"];
}
@end
请注意,您不应将方法命名为displayedItems
。这会产生一个无限循环,因为KVC机器会比ivar更早地找到你的方法。见here。
或者您可以使用Objective-C运行时函数访问任何隐藏的ivar。这也很有趣。
但是,让我再说一遍。知道你可以做一件事并做真实的事情有很大的不同。想想任何可怕的罪行。并亲自做到这一点。
答案 1 :(得分:5)
你不应该真的,但是像指向结构成员的指针一样访问它:
-(NSMutableArray *)displayedItems {
return self->_displayedItems;
}
这是一件脆弱的事情,因为我确信你知道;)
更新:由于您已经提到上述功能无效,请尝试下载到运行时:
-(NSMutableArray *)displayedItems {
NSMutableArray *displayedItems;
object_getInstanceVariable(self, "_displayedItems", (void *)&displayedItems);
return displayedItems;
}
(经过测试,有效)