ios 字符串的静态 NSArray - 如何/在视图控制器中初始化的位置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20544616/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Static NSArray of strings - how/where to initialize in a View Controller
提问by Alexander Farber
In a Master-Detail app I'd like to display a TableView with 5 sections titled:
在主从应用程序中,我想显示一个包含 5 个部分的 TableView,标题为:
- Your Move
- Their Move
- Won Games
- Lost Games
- Options
- 你的举动
- 他们的举动
- 赢得比赛
- 失落的游戏
- 选项
So I create a blank Master-Detail app in Xcode 5.0.2 and then in its MasterViewController.m (which is a UITableViewController) I'm trying to implement the method:
所以我在 Xcode 5.0.2 中创建了一个空白的 Master-Detail 应用程序,然后在它的 MasterViewController.m(这是一个 UITableViewController)中我试图实现该方法:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return _titles[section];
}
My questionis however how to init the NSArray _titles?
我的问题是如何初始化 NSArray _titles?
I'm trying in the MasterViewController.m:
我在 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
{
....
}
but both tries above give me syntax errors:
但上面的两次尝试都给了我语法错误:
UPDATE:
更新:
To my surprise there are many suggestions for this simple question, but as an iOS/Objective-C newbie I'm not sure, which solution is most appropriate.
令我惊讶的是,对于这个简单的问题有很多建议,但作为 iOS/Objective-C 新手,我不确定哪种解决方案最合适。
dispatch_once
- isn't it a runtime operation to execute something once in a multi-threaded app? Isn't it overkill here? I was expecting a compile-time solution for initiating a const array...
dispatch_once
- 在多线程应用程序中执行一次不是一个运行时操作吗?这里是不是太过分了?我期待一个编译时解决方案来启动一个 const 数组......
viewDidLoad
- when my app changes between background and foreground, wouldn't it unnecessary initiate my const array again and again?
viewDidLoad
- 当我的应用程序在后台和前台之间切换时,是否没有必要一次又一次地启动我的 const 数组?
Shouldn't I better set the NSArray
in awakeFromNib
(since I use stroyboard scenes for all my ViewControllers)? Or maybe in initSomething
(is the correct method initWithStyle
?)
我不应该更好地设置NSArray
在awakeFromNib
(因为我用我所有的ViewControllers stroyboard场景)?或者也许在initSomething
(是正确的方法initWithStyle
吗?)
回答by jlehr
Write a class method that returns the array.
编写一个返回数组的类方法。
+ (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;
}
Then you can access it wherever needed like so:
然后你可以在任何需要的地方访问它,如下所示:
NSArray *titles = [[self class] titles];
回答by Emmanuel
You can init it in class method +initialize
您可以在类方法中初始化它+initialize
static NSArray *_titles_1;
@implementation MasterViewController
+ (void)initialize {
_titles_1 = @[
@"Your Move",
@"Their Move",
@"Won Games",
@"Lost Games",
@"Options"
];
}
@end
回答by Pablo A.
You can also do something like this:
你也可以做这样的事情:
static NSString * const strings[] = {
[0] = @"string_1",
[1] = @"string_2",
[2] = @"string_3",
[3] = @"string_4",
// ...
};
It's not an NSArray
but you can access NSStrings
like this strings[n]
这不是一个,NSArray
但你可以NSStrings
像这样访问strings[n]
回答by Anoop Vaidya
You should declare your static array above @implementation
.
你应该在上面声明你的静态数组 @implementation
。
static NSArray *titles_1 = nil;
@implementation ...
And define it in init
or awakeFromNib
or any other method like viewDidLoad
, applicationDidFinishLaunching
wherever you want.
并在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" ]];
}
}
回答by Alexander Farber
I wonder, if the following would be a good way (answering my own question):
我想知道以下是否是一个好方法(回答我自己的问题):
#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"
];
}
This way the const NSArray
is initalized once and right before I need it (in the MasterViewController
class). And the self
check prevents this method from running again - when some inheriting class does not implement its own +initialize
method.
这样const NSArray
就在我需要它之前(在MasterViewController
课堂上)初始化一次。并且self
检查会阻止此方法再次运行 - 当某些继承类没有实现自己的+initialize
方法时。
回答by gnasher729
dispatch_once works. It works in complicated cases, and it works in simple cases. So to be consistent, the best thing is to use it in all cases. That makes it for example a lot easier when you replace all your constant strings with calls to NSLocalizedString (). No code change needed.
dispatch_once 有效。它适用于复杂的情况,也适用于简单的情况。所以要保持一致,最好的办法是在所有情况下都使用它。例如,当您使用对 NSLocalizedString () 的调用替换所有常量字符串时,这会变得容易得多。无需更改代码。
Doing things in + (void)initialize isn't really wrong, but I have had situations where I first wanted to configure a class before really using it, and initialize is of course called just before any possible configuration method would start executing. And there are situations where you don't really have a class context. dispatch_once will always work.
在 + (void)initialize 中做事并没有错,但是我遇到过这样的情况,我首先想在真正使用它之前配置一个类,并且 initialize 是在任何可能的配置方法开始执行之前调用的。在某些情况下,您并没有真正的类上下文。dispatch_once 将始终有效。
回答by Simon McLoughlin
You can't instantiate objects in this way, you can only declare them in interfaces. Do the following:
您不能以这种方式实例化对象,只能在接口中声明它们。请执行下列操作:
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
- or likewise you could use the viewcontroller init method instead of viewDidLoad
- 或者同样你可以使用 viewcontroller init 方法而不是 viewDidLoad
回答by Emmanuel Crombez
Why don't use :
为什么不使用:
+(NSString*)titleForSection:(NSInteger)section {
return (@[ @"title1", @"title2", @"title3" ])[section];
}
回答by rpstw
I prefer to use Objective-C++,change filename from xxx.m
to xxx.mm
,and the initialize of NSArray will happen at runtime
我更喜欢使用 Objective-C++,将文件名从 更改xxx.m
为xxx.mm
,并且 NSArray 的初始化将在运行时发生
nodispatch_once
,noclass method,just write it in one line:
不dispatch_once
,没有类方法,只需写在一行中:
static NSArray *const a = @[@"a",@"b",@"c"];