关联引用的视图层次结构持久性问题

时间:2013-10-17 01:23:14

标签: ios objective-c cocoa-touch objective-c-runtime objective-c-category

我正在尝试创建一个自定义类别来扩展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];
    }
}

1 个答案:

答案 0 :(得分:1)

我不认为这与你的问题有关,但-storedView如果无法找到存储的视图(这很好)就会进行延迟创建,但是它不会关联它只是查看它创建。我也希望它存储视图,这样就没有机会返回一个没有关联的新对象。

其次,我承认我没有使用那种static char const * const键控方法,所以我不知道它是否会让你感到悲伤(一个快速谷歌显示其他人在SO上发布有关员工问题的问题并使用相同的键控方法)。还有另一种方法来键入我使用的相关对象(并且知道正在工作),其中你{'}拥有'关联对象作为关键字。它导致代码更少,并且是自我记录,我很喜欢。

objc_setAssociatedObject(self, @selector(storedView), storedView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);