在Master-Detail应用程序中,我想显示一个TableView,其中有5个部分标题为:
所以我在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
{
....
}
但上面的两次尝试都给出了语法错误:
更新
令我惊讶的是,对于这个简单的问题有很多建议,但作为iOS / Objective-C新手,我不确定,哪种解决方案最合适。
dispatch_once
- 在多线程应用程序中执行某些操作不是运行时操作吗?这不是太过分了吗?我期待一个用于启动const数组的编译时解决方案...
viewDidLoad
- 当我的应用在背景和前景之间切换时,是不是不必要一次又一次地启动我的const数组?
我不应该在NSArray
中更好地设置awakeFromNib
(因为我为所有ViewControllers使用stroyboard场景)?或者也许在initSomething
中(是正确的方法initWithStyle
?)
答案 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 ...
并在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" ]];
}
}
答案 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
答案 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"];