1

我正在尝试创建一个自定义类别来扩展 UIViewController 的功能,并且在这个类别中我想存储一个指向视图的指针以供重用。我正在使用Ole Begemann描述的关联引用。但是,似乎虽然关联引用本身可以存储和检索 UIView,但将该 UIView 添加到 currentView 会将视图添加为子视图,但后续比较(例如,即使(关联引用)确实已经返回)也[self.view.subviews containsObject:self.storedView]将始终返回添加到. 此外,即使已将类似代码添加到视图层次结构中,也会始终出现。我猜这是因为我没有完全理解关联引用是如何工作的。NOself.storedViewself.viewself.storedView.superviewnilself.storedView

有什么想法可能会出错吗?如果有帮助,我可以提供代码示例。

谢谢!


更新 1:这是一个代码片段,说明我如何self.storedView通过关联(关联?)引用在类别中创建,然后尝试从视图控制器的viewviaIBAction方法中添加和删除它。

//  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];
    }
}
4

1 回答 1

1

我认为这与您的问题无关,但是-storedView如果找不到存储的视图(这很好),则会进行延迟创建,但它不会关联它刚刚创建的视图。我也会让它存储视图,这样它就不可能返回一个不相关的新对象。

其次,我承认我没有使用这种static char const * const键控方法,所以我不知道它是否会让你感到悲伤(快速谷歌显示 SO 上的其他人正在发布有关关联问题的问题并使用相同的键控方法)。还有另一种键入我使用的关联对象的方法(并且知道它正在工作),其中您使用选择器作为“拥有”该关联对象的属性/方法作为键。它导致代码更少,并且是我非常喜欢的自我记录。

objc_setAssociatedObject(self, @selector(storedView), storedView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
于 2013-10-17T15:04:15.357 回答