在getter方法中设置属性是不是很糟糕?

时间:2012-05-28 22:16:31

标签: objective-c ios getter accessor

如果我有一个属性,比如一个NSArray,那我的每个实例只会初始化一次,这有什么不妥之处:

(在界面中)

@property(strong, nonatomic)NSArray *bubbleArr;

(在实施中)

-(NSArray*)bubbleArr
{
    if(!bubbleArr)
    {
        NSMutableArray *tempBubbArr = [[NSMutableArray alloc] init];
        // get filepath for first speech bubble image for page
        NSString *speechBubbleImgPath = [[NSBundle mainBundle] pathForResource:
                                         [NSString stringWithFormat:@"speech_%i_0", pageIndex]
                                                                        ofType:@"png"];

        for(int i = 1; speechBubbleImgPath; i++)
        {
            UIImage *speechBubbleImg = [[UIImage alloc] initWithContentsOfFile:speechBubbleImgPath];
            UIImageView *speechBubbleImgView = [[UIImageView alloc] initWithImage:speechBubbleImg];

            [tempBubbArr addObject:speechBubbleImgView];

            speechBubbleImg = nil;
            speechBubbleImgView = nil;
            speechBubbleImgPath = nil;

            speechBubbleImgPath = [[NSBundle mainBundle] pathForResource:
                                   [NSString stringWithFormat:@"speech_%i_%i", pageIndex, i]
                                                                  ofType:@"png"];
        }

        bubbleArr = [[NSArray alloc] initWithArray:tempBubbArr];

        tempBubbArr = nil;
    }

    return bubbleArr;
}

我从来没有使用自定义访问器方法,但这似乎是一种干净的设置方式,所以我不必在viewDidLoad或其他地方设置每个属性,也没有担心它是nil。我不记得曾经遇到过这样做的代码。这是推荐的方法吗?另外,我总是希望使用self.bubbleArr来确保调用此方法,对吧?

4 个答案:

答案 0 :(得分:2)

这是一种完全有效的设置财产的方式。 Apple经常在他们的示例代码和项目模板中执行此类操作。例如,查看新创建的核心数据iOS项目中的核心数据堆栈设置。正如@WendiKidd所指出的那样,你必须一直通过访问器访问你的变量,以确保它能很好地工作(这可能就是你应该做的事情)。

特别是,这是一个实现类的属性的好方法,它实际上只能返回一个东西(从你的注释中,它听起来就像你正在尝试做的那样)。如果这是您的目标,请遵循以下指南:

  1. 将您的财产声明为readonly
  2. 如果它应该是公共可访问的,则在公共标头中声明它,或者如果它应该是“私有”,则在.m文件的类扩展中声明它
  3. 如果它可以/应该由变量支持,请合成ivar并在完成时覆盖getter
  4. 如果它不应该/不必由变量支持,则在实现中将属性声明为@dynamic并覆盖getter
  5. 只能通过访问者访问您的ivar
  6. 在第4点将变量声明为动态将向任何查看您的代码的人发出信号,表明您可能为该属性编写了自定义访问者。

答案 1 :(得分:1)

等待您需要变量内容来初始化它的技术称为“延迟加载”,并且是一种有效的技术。不过,我不确定是在吸气器里面做的。

我认为这个问题完全由你帖子的最后一行描述 - 是的,你总是要确保在想要引用该对象时调用getter方法,即使在类本身内部也是如此。很容易出错并且不能正确地做到这一点,如果您的代码将来可以传递给其他开发人员,那么这是一个特别糟糕的主意。他们绝对不会指望你以这种方式设置,并且当他们期望能够正常访问变量时可能会遇到问题。在viewDidLoad中初始化成员变量是常见且公认的做法。

所以是的 - 这在技术上是可行的,但在设计方面不是一个非常合理的设置。我会强烈反对它。但如果你只是想知道它是否会起作用,答案是肯定的。

答案 2 :(得分:0)

是的,如果您不使用self.bubbleArray或[self bubbleArray],您将不会调用该方法。

除此之外,完全是一种管理财产实例化的好方法。

答案 3 :(得分:0)

这似乎是一个干净的解决方案,感觉有点像延迟加载。但我不确定我会这样做。