Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 访问类别中的私有变量会导致链接器错误_Objective C_Cocoa_Private_Linker Errors_Categories - Fatal编程技术网

Objective c 访问类别中的私有变量会导致链接器错误

Objective c 访问类别中的私有变量会导致链接器错误,objective-c,cocoa,private,linker-errors,categories,Objective C,Cocoa,Private,Linker Errors,Categories,编辑:我不会这么做,我现在意识到这有多危险。但是,这个问题纯粹是出于学术目的 我正在尝试在NSCollectionView上实现一个类别,它将允许我访问私有变量displayedItems。我需要能够在我的子类中访问它。因此,我创建了以下类别: @interface NSCollectionView (displayedItems) - (NSMutableArray *)displayedItems; @end @implementation NSCollectionView (dis

编辑:我不会这么做,我现在意识到这有多危险。但是,这个问题纯粹是出于学术目的

我正在尝试在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打印了它的内容。有人知道解决这个问题的方法吗

提前谢谢

Billy

您不应该真的访问它,而是像访问结构成员的指针一样访问它:

-(NSMutableArray *)displayedItems {
  return self->_displayedItems;
}
这是一件脆弱的事情,但我相信你也知道;)

更新:由于您提到上述操作不起作用,请尝试下拉到运行时:

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

(已测试,有效)

\u displayedItems
是一个私有ivar,因此您不应该访问它,即使是从类别访问它

也就是说,您应该尝试使用

gcc -arch i386

看看有什么不同。在32位模式下,您看不到错误。这表明局势是多么脆弱。你真的不应该

也就是说,有一种方法可以通过滥用KVC获得ivar:

@implementation NSCollectionView (displayedItems)

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

@end
请注意,您不应该将方法命名为
displayedItems
。这将形成一个无限循环,因为KVC机器将比ivar更早找到您的方法。看

或者,您可以使用Objective-C运行时函数访问任何隐藏的ivar。那也很有趣

不过,让我再说一遍。知道自己可以做一件事和真正做那件事有很大的不同。想想任何可怕的罪行。而且是你自己做的


不要那样做!!!!!这也不起作用,它给出了一个相同的错误。不过,谢谢你的建议!这是一个技术上正确的答案,但不是道德上正确的答案:是啊,我认为OP已经做出决定,根据问题的性质,忽略任何关于脆弱性的担忧,但我100%同意你的看法:)这确实有效,但我决定倾听不这样做的请求,并设计了另一种获取信息的方法,这种方法不需要任何不道德的东西无论如何谢谢你!我会将“不要那样做”移到顶部。:)如果你开始研究框架类的内部状态,你肯定会惊讶于随着时间的推移崩溃和神秘的失败。@bbum在另一个答案中建议的
对象\u getInstanceVariable
不是相对无害吗?你正在挂起那些内部实现细节可能会改变的对象的状态。考虑NStUnt,其值可以是单元格,也可以是每个平台的更改。将统计数据注入中间系统类是一个糟糕的设计@YarThank@bbum,没错,它打破了封装,感谢您的回复。我发现这是最好的答案。简单、简单、安全:
@implementation NSCollectionView (displayedItems)

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

@end