静态NSArray字符串 - 在View Controller中初始化的方式/位置

时间:2013-12-12 13:17:24

标签: ios objective-c nsmutablearray initialization nsarray

在Master-Detail应用程序中,我想显示一个TableView,其中有5个部分标题为:

  1. 你的举动
  2. 他们的举动
  3. 赢得比赛
  4. 迷失游戏
  5. 选项
  6. 所以我在Xcode 5.0.2中创建一个空白的Master-Detail应用程序,然后在其MasterViewController.m(这是一个UITableViewController)中创建我正在尝试实现该方法:

    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
        return _titles[section];
    }
    

    我的问题是如何初始化NSArray _titles的?

    我正在尝试使用MasterViewController.m:

    #import "MasterViewController.h"
    #import "DetailViewController.h"
    
    static NSArray *_titles_1 = @[
        @"Your Move",
        @"Their Move",
        @"Won Games",
        @"Lost Games",
        @"Options"
    ];
    
    @interface MasterViewController () {
        NSMutableArray *_games;
    
        NSArray *_titles_2 = @[
                             @"Your Move",
                             @"Their Move",
                             @"Won Games",
                             @"Lost Games",
                             @"Options"
        ];
    }
    @end
    
    @implementation MasterViewController
    
    - (void)awakeFromNib
    {
        if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
            self.clearsSelectionOnViewWillAppear = NO;
            self.preferredContentSize = CGSizeMake(320.0, 600.0);
        }
        [super awakeFromNib];
    }
    
    - (void)viewDidLoad
    {
         ....
    }
    

    但上面的两次尝试都给出了语法错误:

    enter image description here

    更新

    令我惊讶的是,对于这个简单的问题有很多建议,但作为iOS / Objective-C新手,我不确定,哪种解决方案最合适。

    dispatch_once - 在多线程应用程序中执行某些操作不是运行时操作吗?这不是太过分了吗?我期待一个用于启动const数组的编译时解决方案...

    viewDidLoad - 当我的应用在背景和前景之间切换时,是不是不必要一次又一次地启动我的const数组?

    我不应该在NSArray中更好地设置awakeFromNib(因为我为所有ViewControllers使用stroyboard场景)?或者也许在initSomething中(是正确的方法initWithStyle?)

9 个答案:

答案 0 :(得分:79)

编写一个返回数组的类方法。

+ (NSArray *)titles
{
    static NSArray *_titles;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _titles = @[@"Your Move",
                    @"Their Move",
                    @"Won Games",
                    @"Lost Games",
                    @"Options"];
    });
    return _titles;
}

然后您可以在任何需要的地方访问它,如下所示:

NSArray *titles = [[self class] titles];

答案 1 :(得分:12)

您可以在类方法+initialize

中初始化它
static NSArray *_titles_1;

@implementation MasterViewController
+ (void)initialize {
    _titles_1 = @[
        @"Your Move",
        @"Their Move",
        @"Won Games",
        @"Lost Games",
        @"Options"
    ];
}
@end

答案 2 :(得分:7)

您应该将您的静态数组声明为@implementation

static NSArray *titles_1 = nil;

@implementation ...

并在initawakeFromNib或任何其他方法(例如viewDidLoadapplicationDidFinishLaunching中定义它。

- (void)initMethod{ //change the method name accordingly

    if (titles_1 == nil){
        [self setTitles_1:@[ @"Your Move", @"Their Move", @"Won Games", @"Lost Games", @"Options" ]];
    }
}

答案 3 :(得分:7)

您也可以这样做:

static NSString * const strings[] = {
        [0] = @"string_1",
        [1] = @"string_2",
        [2] = @"string_3",
        [3] = @"string_4",
        // ...
    };

它不是NSArray,但您可以NSStrings strings[n]访问[gitweb] type = cgit url = https://gerritServer/cgit/

答案 4 :(得分:6)

我想知道,如果以下是一个好方法(回答我自己的问题):

#import "MasterViewController.h"
#import "DetailViewController.h"

static const NSArray *_titles;

@interface MasterViewController () {
    NSMutableArray *_objects;
    NSMutableArray *_yourMove;
    NSMutableArray *_theirMove;
    NSMutableArray *_wonGames;
    NSMutableArray *_lostGames;
    NSMutableArray *_options;
}
@end

@implementation MasterViewController

+ (void)initialize
{
    // do not run for derived classes
    if (self != [MasterViewController class])
        return;

    _titles = @[
        @"Your Move",
        @"Their Move",
        @"Won Games",
        @"Lost Games",
        @"Options"
    ];
}

这样const NSArray就会在我需要它之前就被初始化(在MasterViewController类中)。 self检查会阻止此方法再次运行 - 当某些继承类没有实现自己的+initialize方法时。

答案 5 :(得分:2)

您无法以这种方式实例化对象,您只能在接口中声明它们。执行以下操作:

static NSArray *_titles_2;

@interface MasterViewController () {
    NSMutableArray *_games;
}
@end

@implementation MasterViewController
-(void)viewDidLoad()
{
     _titles_2 = @[
                         @"Your Move",
                         @"Their Move",
                         @"Won Games",
                         @"Lost Games",
                         @"Options"
    ];
}
@end
  • 或类似地,您可以使用viewcontroller init方法而不是viewDidLoad

答案 6 :(得分:2)

dispatch_once有效。它适用于复杂的情况,并且在简单的情况下工作。所以为了保持一致,最好的办法就是在所有情况下使用它。通过调用NSLocalizedString()替换所有常量字符串,这使得它更容易。无需更改代码。

在+(void)初始化中做一些事情并不是真的错了,但是在我真正使用它之前我首先想要配置一个类的情况,并且当然在任何可能的配置方法开始执行之前调用初始化。在某些情况下,您实际上没有类上下文。 dispatch_once将始终有效。

答案 7 :(得分:0)

为什么不使用:

+(NSString*)titleForSection:(NSInteger)section {
    return (@[ @"title1", @"title2", @"title3" ])[section];
}

答案 8 :(得分:-1)

我更喜欢使用Objective-C ++,将文件名从xxx.m更改为xxx.mm,NSArray的初始化将在运行时发生

没有 dispatch_once没有类方法,只需将其写在一行:

static NSArray *const a = @[@"a",@"b",@"c"];