【问题标题】:How to initialize NSArrays / NSMutableArrays when declared as properties声明为属性时如何初始化 NSArrays / NSMutableArrays
【发布时间】:2013-09-13 20:43:30
【问题描述】:

我需要一些帮助来了解如何使用 NSArrays / NSMutableArrays 作为属性。

  1. 数组应该是什么属性:强或复制?在什么情况下我应该使用哪个属性?
  2. 如何在代码中初始化数组。
  3. 我的属性数组应该是 NSArray 还是 NSMutableArray

目前我的做法有两种不同的方式,如下所示。但这一切都是零散的,并且没有清楚地了解它的机制。哪一项是正确的还是错误的。

方法 1


 .m file
    interface() 
           @property (nonatomic, strong) NSMutableArray *arrayOfData;
    implementation
         <....other code>

          self.arrayOfData = [NSMutableArray arrayWithCapacity:count];
         [self.arrayOfData addObject:<my object>]

方法 2


 .h file
         @property (nonatomic, strong) NSArray *arrayOfData;
 .m file
     //Property setter
        - (void)setListOfData:(NSMutableArray *)newList {
              if (_arrayOfData != newList) {
                    _arrayOfData = [newList copy];
              }
          }     

     //Function which initializes the arrayOfData

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

       .....<code which adds data>
       self.arrayOfData = newData;

【问题讨论】:

  • 这太笼统了。我可以为你的每一个问题写一本书的一整章。
  • 您需要指定这是一个创建为空并随时间修改的数组,还是一个概念上(如果不是实际上)只读的数组,在创建时完全初始化,并且以后永远不会修改.
  • 正在修改数组。我正在使用 addObject 将数据添加到数组中。我的困惑是如何实际初始化它,当我在代码中使用方法1或方法2时,即在setter / getter之外

标签: objective-c nsmutablearray nsarray


【解决方案1】:

NSArray 或 NSMutableArray

嗯,是使用NSArray 还是NSMutableArray 在很大程度上取决于您的用例。 您是否在运行时更改了数组的内容,但这里或那里只有几个项目?使用NSMutableArray(非常适合可编辑的UITableViews 数据源)。您是否总是用全新的数据重新加载数据源?在这种情况下,我只会使用NSArray

强或复制

这又取决于你想做什么。如果,当有人调用该属性时,您希望他们获得自己的数据源副本,请使用copy。但我实际上从未以这种方式使用它,我认为对于 90% 的用例,使用strong 会更好。这意味着.arrayOfData 的调用者在你的类中获得了一个指向NSArray 的指针(因此可以检测到它的变化)。

如何使用

正如我所提到的,我通常使用NSMutableArray 来表示UITableView 数据源。在头文件中我有

@property (nonatomic, strong) NSMutableArray *arrayOfData;

和你一样。我的不同之处在于,在.m 文件中,我覆盖getter 以懒惰地为我创建一个NSMutableArray。因此,我将不理会 setter 并放置以下 getter 实现。

- (NSMutableArray *) arrayOfData
{
    if (!_arrayOfData) {
        _arrayOfData = [NSMutableArray new];
    }
    return _arrayOfData;
}

这样,当您第一次在类中使用self.arrayOfData 时,它会被分配、初始化并保存到实例变量中。然后从第二次开始,它将继续返回实例变量。希望这能澄清一点。

编辑

示例用例:您有一个 Twitter 客户端,其中 TwTableViewController 显示推文列表。假设您将有一个名为 -(NSArray*)_getNewTweets 的私有方法,它将从服务器获取推文并返回一个 NSArray 与它们。为此,您还需要创建一个 fetchNewData 方法。请参阅下面的流程。

TwTableViewController.h:

@interface TwTableViewController : UITableViewController
@property (nonatomic, strong) * downloadedTweets;
- (void) fetchNewData;
@end

TwTableViewController.m:

@implementation TwTableViewController

- (NSMutableArray *) downloadedTweets
{
    if (!_downloadedTweets) {
        _downloadedTweets = [NSMutableArray new];
    }
    return _downloadedTweets;
}

- (NSArray *)_getNewTweets
{
    NSArray * newTweets = ... //whatever magic to download new tweets
    return newTweets;
}

- (void) fetchNewData
{
    [self.downloadedTweets addObjectsFromArray:[self _getNewTweets]];
    [self.tableView reloadData]; //animated would be prettier, but out of this scope
}

- (void) viewDidLoad
{
    [super viewDidLoad];
    [self fetchNewData];
}

//tableview stuff

@end

第一次调用self.downloadedTweets 时,数组将被创建为空,您可以继续添加/移动/删除项目。不需要为另一个覆盖这个数组,一个就足够了。我使用了-addObjectsFromArray:,当然你也可以使用-addObject:。现在清楚了吗?

【讨论】:

  • 它有点清楚了。 getter 将返回一个空数组,现在如何向其中添加数据。我是直接向它添加数据,即 [self.arrayOfData addObject:] 行,还是创建一个本地 nsmutable 数组,向其中添加数据,然后将该本地数组分配给我的属性数组,即 NSMutableArray *localArray = [[NSMutableArray alloc] init] [localArray addObject:]。然后说 self.arrayOfData = localArray;或 self.arrayOfData = [localArray 副本]
  • 让我扩展我的答案来回答这个问题。
  • 另外,copy 方法只做浅拷贝,你知道吗?所以如果你有NSArray * arr = @[a, b, c] 并调用NSArray * arrCopy = [arr copy],你的arrCopy == @[a, b, c],而不是arrCopy != @[aCopy, bCopy, cCopy]
  • +1。很好的解释。你有什么办法可以向我解释 self.myArray 在你的类的 .m 文件中的方法范围内做什么?
  • @Chisx 抱歉,我不确定我是否理解您的问题。你能详细说明一下吗?
猜你喜欢
  • 1970-01-01
  • 2011-03-06
  • 2016-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-26
  • 1970-01-01
  • 2017-11-20
相关资源
最近更新 更多