我有一些代码,但我看不出如何优化它。虽然我知道代码编写得很糟糕(我自己)。
我所拥有的是火车站名称列表。我想要做的是将这些电台名称添加到tableview,并为每个电台名称的第一个字母添加一个部分。应跳过那些没有任何电台的部分。
第一部分应称为“ - ”,并应显示最近的电台。
示例:
--A--
Astation C
Alaska C
Alabama C
--C--
Cstation
Cathedral station
Central station
所以我得到了所有这些工作,但我觉得我做得很多,应该有一个更简单的方法。此外,在我的iPhone 4上加载此视图时,应用程序挂起1秒钟。这也不好。 这是我的代码:
- (void)viewDidLoad{
self.filteredListContent = [NSMutableArray array];
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch
target:self
action:@selector(searchBar:)];
self.navigationItem.rightBarButtonItem = rightBarButton;
[rightBarButton release];
UISearchBar *mySearchBar = [[UISearchBar alloc] init];
mySearchBar.delegate = self;
[mySearchBar setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[mySearchBar sizeToFit];
theTable.tableHeaderView = mySearchBar;
if (UIInterfaceOrientationLandscapeRight == [[UIDevice currentDevice] orientation] ||
UIInterfaceOrientationLandscapeLeft == [[UIDevice currentDevice] orientation])
{
theTable.tableHeaderView.frame = CGRectMake(0.f, 0.f, 480.f, 44.f);
}
else
{
theTable.tableHeaderView.frame = CGRectMake(0.f, 0.f, 320.f, 44.f);
}
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:mySearchBar contentsController:self];
[self setSearchDisplayController:searchDisplayController];
[searchDisplayController setDelegate:self];
[searchDisplayController setSearchResultsDataSource:self];
[mySearchBar release];
/* Set the data */
NSArray *stationenPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *stationenDocumentsDirectory = [stationenPath objectAtIndex:0];
NSString *path = [stationenDocumentsDirectory stringByAppendingPathComponent:@"stations.plist"];
NSDictionary* stationenDictionary = [[[NSDictionary alloc] initWithContentsOfFile:path] autorelease];
xmlStationenList* stationsXml = [[xmlStationenList alloc] initWithDictionary:stationenDictionary];
NSSortDescriptor *stationSorter = [[NSSortDescriptor alloc] initWithKey:@"_station" ascending:YES];
NSMutableArray *xmlResult = [stationsXml getTimeResult];
NSArray *objects = [[[NSArray alloc] initWithObjects:stationSorter,nil] autorelease];
[xmlResult sortUsingDescriptors:objects];
[stationSorter release];
/* prefName is decided by the page opening chooseStationViewController. Using this class init function */
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
self.prefValue = [prefs valueForKey:prefName];
self.listContent = [NSMutableArray array];
for (stationenListSet *theList in xmlResult)
{
[self.listContent addObject:[theList get_station]];
}
/* END set the data */
/* Set sections */
self.sectionArray = [NSMutableArray array];
[self.sectionArray addObject:@"-"];
[self.sectionArray addObject:@"A"];
[self.sectionArray addObject:@"B"];
[self.sectionArray addObject:@"C"];
[self.sectionArray addObject:@"D"];
[self.sectionArray addObject:@"E"];
[self.sectionArray addObject:@"F"];
[self.sectionArray addObject:@"G"];
[self.sectionArray addObject:@"H"];
[self.sectionArray addObject:@"I"];
[self.sectionArray addObject:@"J"];
[self.sectionArray addObject:@"K"];
[self.sectionArray addObject:@"L"];
[self.sectionArray addObject:@"M"];
[self.sectionArray addObject:@"N"];
[self.sectionArray addObject:@"O"];
[self.sectionArray addObject:@"P"];
[self.sectionArray addObject:@"Q"];
[self.sectionArray addObject:@"R"];
[self.sectionArray addObject:@"S"];
[self.sectionArray addObject:@"T"];
[self.sectionArray addObject:@"U"];
[self.sectionArray addObject:@"V"];
[self.sectionArray addObject:@"W"];
[self.sectionArray addObject:@"X"];
[self.sectionArray addObject:@"Y"];
[self.sectionArray addObject:@"Z"];
[self.sectionArray addObject:@"Å"];
[self.sectionArray addObject:@"Ä"];
[self.sectionArray addObject:@"Ö"];
[sectionSubArray release];
sectionSubArray = [[NSMutableArray alloc] init];
NSMutableArray *sectionTempArray = [[NSMutableArray alloc] init];
[sectionTempArray addObject:@"-"];
[sectionSubArray addObject:[[NSArray alloc] init]];
for(NSString *sectionChar in self.sectionArray)
{
sectionChar = [sectionChar uppercaseString];
int i = 0;
NSMutableArray *sectionRowArray = [[NSMutableArray alloc] init];
for (NSString* theStation in listContent)
{
NSString *firstChar = [[NSString alloc] initWithFormat:@"%C", toupper([theStation characterAtIndex:0])];
if([firstChar isEqualToString:sectionChar])
{
[sectionRowArray addObject:theStation];
i++;
}
[firstChar release];
}
if(i > 0)
{
[sectionSubArray addObject:sectionRowArray];
[sectionTempArray addObject:sectionChar];
}
[sectionRowArray release];
}
self.sectionArray = sectionTempArray;
[sectionTempArray release];
[theTable reloadData];
theTable.scrollEnabled = YES;
[stationsXml release];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
我做的愚蠢的事情是,我为每个字母循环通过我的300多个对象的数组。但我无法找到更好的方法来做到这一点。
最好的问候,
保罗佩伦
--------结果--------
由于您的所有答案,这就是结果:
- (void)viewDidLoad{
self.filteredListContent = [NSMutableArray array];
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch
target:self
action:@selector(searchBar:)];
self.navigationItem.rightBarButtonItem = rightBarButton;
[rightBarButton release];
UISearchBar *mySearchBar = [[UISearchBar alloc] init];
mySearchBar.delegate = self;
[mySearchBar setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[mySearchBar sizeToFit];
theTable.tableHeaderView = mySearchBar;
if (UIInterfaceOrientationLandscapeRight == [[UIDevice currentDevice] orientation] ||
UIInterfaceOrientationLandscapeLeft == [[UIDevice currentDevice] orientation])
{
theTable.tableHeaderView.frame = CGRectMake(0.f, 0.f, 480.f, 44.f);
}
else
{
theTable.tableHeaderView.frame = CGRectMake(0.f, 0.f, 320.f, 44.f);
}
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:mySearchBar contentsController:self];
[self setSearchDisplayController:searchDisplayController];
[searchDisplayController setDelegate:self];
[searchDisplayController setSearchResultsDataSource:self];
[mySearchBar release];
/* Set the data */
NSArray *stationenPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *stationenDocumentsDirectory = [stationenPath objectAtIndex:0];
NSString *path = [stationenDocumentsDirectory stringByAppendingPathComponent:@"stations.plist"];
NSDictionary* stationenDictionary = [[[NSDictionary alloc] initWithContentsOfFile:path] autorelease];
xmlStationenList* stationsXml = [[xmlStationenList alloc] initWithDictionary:stationenDictionary];
NSSortDescriptor *stationSorter = [[NSSortDescriptor alloc] initWithKey:@"_station" ascending:YES];
NSMutableArray *xmlResult = [stationsXml getTimeResult];
NSArray *objects = [[[NSArray alloc] initWithObjects:stationSorter,nil] autorelease];
[xmlResult sortUsingDescriptors:objects];
[stationSorter release];
/* prefName is decided by the page opening chooseStationViewController. Using this class init function */
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
self.prefValue = [prefs valueForKey:prefName];
self.listContent = [NSMutableArray array];
for (stationenListSet *theList in xmlResult)
{
[self.listContent addObject:[theList get_station]];
}
/* END set the data */
/* Set sections */
self.sectionArray = [[NSArray alloc] initWithObjects:@"-", @"A", @"B", @"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"N", @"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"W", @"X", @"Y", @"Z", @"Å", @"Ä", @"Ö", nil];
NSMutableDictionary *sectionDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[[NSMutableArray alloc] init], @"-",
[[NSMutableArray alloc] init], @"A",
[[NSMutableArray alloc] init], @"B",
[[NSMutableArray alloc] init], @"C",
[[NSMutableArray alloc] init], @"D",
[[NSMutableArray alloc] init], @"E",
[[NSMutableArray alloc] init], @"F",
[[NSMutableArray alloc] init], @"G",
[[NSMutableArray alloc] init], @"H",
[[NSMutableArray alloc] init], @"I",
[[NSMutableArray alloc] init], @"J",
[[NSMutableArray alloc] init], @"K",
[[NSMutableArray alloc] init], @"L",
[[NSMutableArray alloc] init], @"M",
[[NSMutableArray alloc] init], @"N",
[[NSMutableArray alloc] init], @"O",
[[NSMutableArray alloc] init], @"P",
[[NSMutableArray alloc] init], @"Q",
[[NSMutableArray alloc] init], @"R",
[[NSMutableArray alloc] init], @"S",
[[NSMutableArray alloc] init], @"T",
[[NSMutableArray alloc] init], @"U",
[[NSMutableArray alloc] init], @"V",
[[NSMutableArray alloc] init], @"W",
[[NSMutableArray alloc] init], @"X",
[[NSMutableArray alloc] init], @"Y",
[[NSMutableArray alloc] init], @"Z",
[[NSMutableArray alloc] init], @"Å",
[[NSMutableArray alloc] init], @"Ä",
[[NSMutableArray alloc] init], @"Ö", nil];
[sectionSubArray release];
sectionSubArray = [[NSMutableArray alloc] init];
for(NSString *theStation in listContent) {
NSString *firstChar = [[[NSString alloc] initWithFormat:@"%C", toupper([theStation characterAtIndex:0])] uppercaseString];
[[sectionDictionary objectForKey:firstChar] addObject:theStation];
}
NSArray *keys = [sectionDictionary allKeys];
keys = [keys sortedArrayUsingSelector:@selector(localizedCompare:)];
int indexPath = 0;
NSMutableArray *sectionTempArray = [[NSMutableArray alloc] init];
[sectionTempArray addObject:@"-"];
[sectionSubArray addObject:[[NSArray alloc] init]];
for(NSString *key in keys)
{
if ([[sectionDictionary objectForKey:key] count] > 0)
{
NSArray *subArray = [[sectionDictionary objectForKey:key] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
[sectionTempArray addObject:key];
[sectionSubArray addObject:subArray];
}
indexPath++;
}
self.sectionArray = sectionTempArray;
[sectionTempArray release];
[theTable reloadData];
theTable.scrollEnabled = YES;
[stationsXml release];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
答案 0 :(得分:2)
这是带有fiew更改的代码。这些是我所做的改变:
1)使用局部变量而不是加载sectionArray 26次 2)循环站一次而不是29次
你有没有把代码留在某个地方? sectionSubArray未在此函数中定义,但似乎是局部变量。它也从未被分配给一个财产。
- (void)viewDidLoad{
self.filteredListContent = [NSMutableArray array];
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch
target:self
action:@selector(searchBar:)];
self.navigationItem.rightBarButtonItem = rightBarButton;
[rightBarButton release];
UISearchBar *mySearchBar = [[UISearchBar alloc] init];
mySearchBar.delegate = self;
[mySearchBar setAutocapitalizationType:UITextAutocapitalizationTypeNone];
[mySearchBar sizeToFit];
theTable.tableHeaderView = mySearchBar;
if (UIInterfaceOrientationLandscapeRight == [[UIDevice currentDevice] orientation] ||
UIInterfaceOrientationLandscapeLeft == [[UIDevice currentDevice] orientation])
{
theTable.tableHeaderView.frame = CGRectMake(0.f, 0.f, 480.f, 44.f);
}
else
{
theTable.tableHeaderView.frame = CGRectMake(0.f, 0.f, 320.f, 44.f);
}
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:mySearchBar contentsController:self];
[self setSearchDisplayController:searchDisplayController];
[searchDisplayController setDelegate:self];
[searchDisplayController setSearchResultsDataSource:self];
[mySearchBar release];
/* Set the data */
NSArray *stationenPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *stationenDocumentsDirectory = [stationenPath objectAtIndex:0];
NSString *path = [stationenDocumentsDirectory stringByAppendingPathComponent:@"stations.plist"];
NSDictionary* stationenDictionary = [[[NSDictionary alloc] initWithContentsOfFile:path] autorelease];
xmlStationenList* stationsXml = [[xmlStationenList alloc] initWithDictionary:stationenDictionary];
NSSortDescriptor *stationSorter = [[NSSortDescriptor alloc] initWithKey:@"_station" ascending:YES];
NSMutableArray *xmlResult = [stationsXml getTimeResult];
NSArray *objects = [[[NSArray alloc] initWithObjects:stationSorter,nil] autorelease];
[xmlResult sortUsingDescriptors:objects];
[stationSorter release];
/* prefName is decided by the page opening chooseStationViewController. Using this class init function */
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
self.prefValue = [prefs valueForKey:prefName];
self.listContent = [NSMutableArray array];
for (stationenListSet *theList in xmlResult)
{
[self.listContent addObject:[theList get_station]];
}
/* END set the data */
/* Set sections */
NSMutableArray *sectionTempArray = [NSMutableArray array];
self.sectionArray = sectionTempArray;
[sectionTempArray addObject:@"-"];
[sectionTempArray addObject:@"A"];
[sectionTempArray addObject:@"B"];
[sectionTempArray addObject:@"C"];
[sectionTempArray addObject:@"D"];
[sectionTempArray addObject:@"E"];
[sectionTempArray addObject:@"F"];
[sectionTempArray addObject:@"G"];
[sectionTempArray addObject:@"H"];
[sectionTempArray addObject:@"I"];
[sectionTempArray addObject:@"J"];
[sectionTempArray addObject:@"K"];
[sectionTempArray addObject:@"L"];
[sectionTempArray addObject:@"M"];
[sectionTempArray addObject:@"N"];
[sectionTempArray addObject:@"O"];
[sectionTempArray addObject:@"P"];
[sectionTempArray addObject:@"Q"];
[sectionTempArray addObject:@"R"];
[sectionTempArray addObject:@"S"];
[sectionTempArray addObject:@"T"];
[sectionTempArray addObject:@"U"];
[sectionTempArray addObject:@"V"];
[sectionTempArray addObject:@"W"];
[sectionTempArray addObject:@"X"];
[sectionTempArray addObject:@"Y"];
[sectionTempArray addObject:@"Z"];
[sectionTempArray addObject:@"Å"];
[sectionTempArray addObject:@"Ä"];
[sectionTempArray addObject:@"Ö"];
[sectionSubArray release];
sectionSubArray = [[NSMutableArray alloc] init];
sectionTempArray = [[NSMutableArray alloc] init];
[sectionTempArray addObject:@"-"];
[sectionSubArray addObject:[[NSArray alloc] init]];
NSMutableArray *sectionRowArrays[29];
memset(sectionRowArrays,0,sizeof(NSMutableArray*)*29);
for(NSString *theStation in listContent) {
char currChar = toupper([theStation characterAtIndex:0]);
uint8_t index;
if(currChar == 'Å') index = 26;
else if(currChar == 'Ä') index = 27;
else if(currChar == 'Ö') index = 28;
else index = currChar - 'A';
if(!sectionRowArrays[index]) sectionRowArrays[index] = [[NSMutableArray alloc] init];
[sectionRowArrays[index] addObject:theStation];
}
for(uint8_t index = 0; index < 29; ++index) {
if(sectionRowArrays[index]) {
[sectionSubArray addObject:sectionRowArrays[index]];
NSString *currChar;
if(index == 26) currChar = @"Å";
else if(index == 27) currChar = @"Ä";
else if(index == 28) currChar = @"Ö";
else currChar = [NSString stringWithFormat:@"%c",index+'A'];
[sectionTempArray addObject:currChar];
[sectionRowArrays[index] release];
}
}
self.sectionArray = sectionTempArray;
[sectionTempArray release];
[theTable reloadData];
theTable.scrollEnabled = YES;
[stationsXml release];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate=self;
locationManager.desiredAccuracy=kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
答案 1 :(得分:1)
如何迭代站点列表并简单地将每个站点添加到相应的“桶”中?
如果您不需要NSObjects和NSArrays,那么您可以考虑使用标准模板库'map&lt;&gt;模板。但是如果你不熟悉它,那么它可能会带来更多的复杂性(就学习曲线而言)而不是它的价值。
简而言之,NSMtringDictionary如何使用NSString键作为第一个字母,而对象是NSMutableArrays。
我还没有这样做 - 但它会将你的30x300迭代减少到300。
答案 2 :(得分:1)
如果您想花时间改进需要时间的代码,则需要对应用的执行情况进行分析。
提示1:在这里使用unichar,它将节省数百或数千个分配:
NSString *firstChar = [[NSString alloc] initWithFormat:@"%C", toupper([theStation characterAtIndex:0])];
提示2:使用增量增长填充了几个集合。它将有助于尽可能减少增长/重新分配的数量。苹果的第二个猜测已经存在,所以他们基于现实世界使用的优化有时会对你有利,但不一定总是如此。如果你在人口中过度分配了你的馆藏,你可以通过创建一个副本然后处理临时文件来展平它们。
提示3:尽可能避免自动释放的对象。 (严重)
当然,您也希望优化搜索/排序/填充算法。
但严重的是,如果您想了解您的时间花在哪里,您必须进行分析。
祝你好运!答案 3 :(得分:1)
只是添加其他答案,因为这是一个小得多的东西,并不是那么重要,但你应该至少知道一些。
此:
NSMutableArray *sectionTempArray = [NSMutableArray array];
self.sectionArray = sectionTempArray;
[sectionTempArray addObject:@"-"];
[sectionTempArray addObject:@"A"];
[sectionTempArray addObject:@"B"];
[sectionTempArray addObject:@"C"];
[sectionTempArray addObject:@"D"];
[sectionTempArray addObject:@"E"];
[sectionTempArray addObject:@"F"];
[sectionTempArray addObject:@"G"];
[sectionTempArray addObject:@"H"];
[sectionTempArray addObject:@"I"];
[sectionTempArray addObject:@"J"];
[sectionTempArray addObject:@"K"];
[sectionTempArray addObject:@"L"];
[sectionTempArray addObject:@"M"];
[sectionTempArray addObject:@"N"];
[sectionTempArray addObject:@"O"];
[sectionTempArray addObject:@"P"];
[sectionTempArray addObject:@"Q"];
[sectionTempArray addObject:@"R"];
[sectionTempArray addObject:@"S"];
[sectionTempArray addObject:@"T"];
[sectionTempArray addObject:@"U"];
[sectionTempArray addObject:@"V"];
[sectionTempArray addObject:@"W"];
[sectionTempArray addObject:@"X"];
[sectionTempArray addObject:@"Y"];
[sectionTempArray addObject:@"Z"];
[sectionTempArray addObject:@"Å"];
[sectionTempArray addObject:@"Ä"];
[sectionTempArray addObject:@"Ö"];
可以替换为:
NSArray sectionTempArray = [[NSArray alloc] initWithObjects: @"-", @"A", @"B",
@"C", @"D", @"E", @"F", @"G", @"H", @"I", @"J", @"K", @"L", @"M", @"N",
@"O", @"P", @"Q", @"R", @"S", @"T", @"U", @"V", @"W", @"X", @"Y", @"Z",
@"Å", @"Ä", @"Ö", nil];
消除了对Mutable数组的需求(减少开销),如果编译器不能优化那些30个addObject调用,那么可以加快速度。如果在初始化之后不需要更改NSArray(或NSString或NSDictionary等)的内容,请不要使用Mutable版本,如果可以的话。