我正在尝试创建一个自定义类别来扩展UIViewController的功能,在这个类别中,我想存储一个指向视图的指针以供重用。我正在使用Ole Begemann所描述的关联引用。但是,似乎虽然关联引用本身可以存储和检索UIView,但是将UIView添加到currentView会将视图添加为子视图,但后续比较(例如[self.view.subviews containsObject:self.storedView]
)将始终返回NO
即使self.storedView
(关联参考)确实已添加到self.view
。此外,即使self.storedView.superview
已添加到视图层次结构中,nil
之类的代码也会始终显示self.storedView
。我猜这是因为我没有完全理解关联引用是如何工作的。
任何想法可能会出错?如果有帮助,我可以提供代码示例。
谢谢!
更新1:以下是关于如何通过关联(关联?)引用在类别中创建self.storedView
,然后尝试在视图中添加和删除它的代码段控制器的view
通过IBAction
方法。
// UIViewController+TestCategory.m
#import <objc/runtime.h>
static char const * const StoredViewKey = "storedView";
- (void)setStoredView:(UIView *)storedView
{
objc_setAssociatedObject(self, StoredViewKey, storedView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (UIView *)storedView
{
UIView *storedView = objc_getAssociatedObject(self, StoredViewKey);
if (!storedView)
{
storedView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.bounds.size.width/2.0, self.view.bounds.size.height/2.0)];
[storedView setBackgroundColor:[UIColor colorWithRed:0.0 green:1.0 blue:0.0 alpha:0.25]];
[storedView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin)];
}
return storedView;
}
- (IBAction)buttonActionAddStoredView:(id)sender
{
if (![self.view.subviews containsObject:self.storedView]) // always returns YES
{
[self.view addSubview:self.storedView];
}
}
- (IBAction)buttonActionRemoveStoredView:(id)sender
{
if ([self.view.subviews containsObject:self.storedView]) // always returns NO
{
[self.storedView removeFromSuperview];
}
}
答案 0 :(得分:1)
我不认为这与你的问题有关,但-storedView
如果无法找到存储的视图(这很好)就会进行延迟创建,但是它不会关联它只是查看它创建。我也希望它存储视图,这样就没有机会返回一个没有关联的新对象。
其次,我承认我没有使用那种static char const * const
键控方法,所以我不知道它是否会让你感到悲伤(一个快速谷歌显示其他人在SO上发布有关员工问题的问题并使用相同的键控方法)。还有另一种方法来键入我使用的相关对象(并且知道正在工作),其中你{'}拥有'关联对象作为关键字。它导致代码更少,并且是自我记录,我很喜欢。
objc_setAssociatedObject(self, @selector(storedView), storedView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);