【问题标题】:Why Do I Have to Create An Object and Assign It to A Property in Objective C?为什么我必须在 Objective C 中创建一个对象并将其分配给一个属性?
【发布时间】:2011-08-24 02:21:11
【问题描述】:

所以我有这个代码,但它不起作用:

for (NSDictionary *item in data){
    [self.resultsArray addObject:item];
}

self.resultsArray 为零。但后来我把它改成了这样:

NSMutableArray *myDataArray = [[NSMutableArray alloc] init];

for (NSDictionary *item in data){
    [myDataArray addObject:item];
}

self.resultsArray = myDataArray;
[myDataArray release];

现在它起作用了。 self.resultsArray 现在已填充

所以我是 Objective C 的初学者,我想知道为什么我不能直接在属性的 addObject 中使用它。为什么我必须创建另一个可变数组,填充它,将其分配给 resultsArray 属性并释放我创建的可变数组?

提前致谢!

编辑:另外,在我写的很多书里,很多都是这样做的。

【问题讨论】:

    标签: objective-c ios


    【解决方案1】:

    简单的回答

    在向其添加对象之前,您没有初始化 self.resultArray。它只是一个指向 nil 值的指针,直到你 alloc 它。

    self.resultArray = [[NSMutableArray alloc] init]; 在添加对象之前将解决此问题。

    但是,这种分配方式会造成内存泄漏,因此书籍和示例中没有显示。如果self.resultArray 属性被标记为retain 并且通过调用alloc 它将被保留2 次,则可能发生内存泄漏。

    【讨论】:

    • 我明白了。谢谢。我读过很多书,我注意到他们总是做我在代码后半部分所做的事情,而不是分配和初始化属性。任何想法为什么?
    • @Ygam,我已经更新了有关由此产生的内存泄漏的答案。请检查。
    • 呃,你不应该这样做self.resultArray = [[NSMutableArray alloc] init];,因为就像你说的那样,泄漏。看我的回答。
    • 哦,顺便说一句,使用 iOS 5 的 ARC,我需要担心这个吗?
    • @Ygam 对此不确定,但您始终需要关心内存泄漏。
    【解决方案2】:

    如果self.resultsArray 为nil,那么[self.resultsArray addObject:item]NOT 将对象添加到数组中,它什么也不做(因为数组默认为nil,并发送消息到nil 是Objective-C 中的空操作)。当您创建一个可变数组作为局部变量时,您可以向其中添加内容 — 然后,如果您将其分配给属性,那么一切都会按您的预期进行,self.resultsArray 将不再为 nil。

    通常当你有这样的属性时,你会在你的 init 方法中设置它们:

    - (id)init {
        // ...
            self.resultsArray = [NSMutableArray array];
            // or access the ivar directly:
            // _resultsArray = [[NSMutableArray alloc] init];
        // ...
    }
    

    然后,一旦您的对象被初始化,您就可以将东西添加到数组中。同样,如果你不这样做,默认为nil[self.resultsArray addObject:item] 将无效。

    【讨论】:

    • 谢谢!并且使用 iOS 5 的 ARC,我是否需要担心在属性中分配和初始化时的内存泄漏?
    • 你是说ARC?不,您不必担心。您可以使用alloc/init 或仅使用array,编译器将获取保留计数的差异。但是,在尝试使用它之前,您仍然需要创建此数组:)
    • @Ygam 您可以在此处阅读有关 ARC 的更多信息:clang.llvm.org/docs/AutomaticReferenceCounting.html
    【解决方案3】:

    您可能没有初始化数组(我将假设 myDataArray 是一个 NSMutableArray)。

    在你的 init 方法中,调用myDataArray = [NSMutableArray array]; 就可以了

    【讨论】:

      【解决方案4】:

      需要注意的重要一点是,您没有创建另一个可变数组,因为您没有数组开始。仅仅声明一个属性或变量并不会创建一个与之配套的对象。这就是 self.resultsArray 以 nil 开头的原因。

      您拥有的工作代码旨在允许您在保留数组两次时显式释放数组:一次是在分配它时,一次是在将它分配给您的属性时。你只想要其中一个保留,所以你释放一次。

      你可以这样做:

      self.resultsArray = [[NSMutableArray alloc] init];
      [self.resultsArray release];
      
      
      for (NSDictionary *item in data){
          [self.resultsArray addObject:item];
      }
      

      这是更少的代码,但不是很清楚。清晰很重要。

      【讨论】:

        猜你喜欢
        • 2011-08-16
        • 2020-11-05
        • 1970-01-01
        • 2015-09-22
        • 2018-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多