string的静态NSArray – 在视图控制器中如何/在哪里初始化
在一个Master-Detail应用程序中,我想显示一个带有5个部分的TableView:
- 你的举动
- 他们的移动
- 赢得游戏
- 迷失的游戏
- 选项
所以我在Xcode 5.0.2中创build一个空白的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 { .... }
但两个尝试上面给我的语法错误:
更新:
令我惊讶的是,对于这个简单的问题有很多build议,但作为一个iOS / Objective-C的新手,我不确定哪种解决scheme最合适。
dispatch_once
– 是不是一个运行时操作在一个multithreading应用程序中执行一次? 这不是矫枉过正吗? 我期待一个编译时解决scheme来启动一个常量数组…
viewDidLoad
– 当我的应用程序在背景和前景之间变化时,是不是不必要一次又一次地启动我的const数组?
难道我不应该更好地设置在awakeFromNib
NSArray
(因为我使用我所有的ViewControllers stroyboard场景)? 或者也许在initSomething
(是正确的方法initWithStyle
?)
编写一个返回数组的类方法。
+ (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];
你可以在类方法初始化中初始化它
static NSArray *_titles_1; @implementation MasterViewController + (void)initialize { _titles_1 = @[ @"Your Move", @"Their Move", @"Won Games", @"Lost Games", @"Options" ]; } @end
你应该在@implementation
之上声明你的静态数组。
static NSArray *titles_1 = nil; @implementation ...
并定义它在init
或awakeFromNib
或任何其他方法,如viewDidLoad
, applicationDidFinishLaunching
任何你想要的。
- (void)initMethod{ //change the method name accordingly if (titles_1 == nil){ [self setTitles_1:@[ @"Your Move", @"Their Move", @"Won Games", @"Lost Games", @"Options" ]]; } }
你也可以做这样的事情:
static NSString * const strings[] = { [0] = @"string_1", [1] = @"string_2", [2] = @"string_3", [3] = @"string_4", // ... };
这不是一个NSArray
但你可以像这样的strings[n]
访问NSStrings
我想知道,如果以下是一个好方法(回答我自己的问题):
#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
了(在MasterViewController
类中)。 而self
防止这种方法再次运行 – 当一些inheritance类没有实现自己的+initialize
方法。
您不能以这种方式实例化对象,只能在接口中声明它们。 请执行下列操作:
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
dispatch_once的作品。 它在复杂的情况下工作,并在简单的情况下工作。 所以要一致,最好的办法就是在所有情况下使用它。 例如,当你用NSLocalizedString()的调用来replace所有的常量string时,这样做会更容易一些。 无需更改代码。
在+(void)中进行初始化并不是真的错,但是在实际使用它之前,我曾经想过要configuration一个类,初始化当然是在任何可能的configuration方法开始执行之前调用的。 而且有些情况下你并没有真正的课堂背景。 dispatch_once将一直工作。
我更喜欢使用Objective-C ++,将文件名从xxx.m
更改为xxx.mm
,并且NSArray的初始化将在运行时发生
没有 dispatch_once
, 没有类的方法,只写在一行:
static NSArray *const a = @[@"a",@"b",@"c"];