包含NSDictionary中数据的iOS表视图

包含NSDictionary中数据的iOS表视图,ios,objective-c,tableview,Ios,Objective C,Tableview,我不熟悉iOS编程,我需要一些建议。我想创建一个带有部分的表视图,以了解它是如何工作的。我有一些来自模型类user的对象。我使用字典在表视图中填充数据。表视图位于“我的故事板”中的视图控制器中。代码可以工作,但我不知道这是否是处理表中数据的好方法。像我这样做是语义上的错误吗 请看一下我的代码并给我一些建议 我的用户对象(user.h): 将用户填充到数组中的伪函数(在助手类中): 函数创建字典对象(在帮助器类中): TableViewController.m: #import "TableVie

我不熟悉iOS编程,我需要一些建议。我想创建一个带有部分的表视图,以了解它是如何工作的。我有一些来自模型类
user
的对象。我使用字典在表视图中填充数据。表视图位于“我的故事板”中的视图控制器中。代码可以工作,但我不知道这是否是处理表中数据的好方法。像我这样做是语义上的错误吗

请看一下我的代码并给我一些建议

我的用户对象(
user.h
):

将用户填充到数组中的伪函数(在助手类中):

函数创建字典对象(在帮助器类中):

TableViewController.m

#import "TableViewController.h"

@implementation TableViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    helper = [[HelperClass alloc] init];
    users = [[NSMutableArray alloc] init];
    users = [helper createUser];

    dictionaryUsers = [[NSMutableDictionary alloc] init];
    dictionaryUsers = [helper createDictionaryFromArray:users];
    allKeys = [NSArray array];
    allKeys = [dictionaryUsers allKeys];


}


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{    // Return the number of sections.
    return [allKeys count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    NSMutableArray *arrayValuesUsers = [[NSMutableArray alloc] init];
    arrayValuesUsers = [dictionaryUsers objectForKey:[allKeys objectAtIndex:section]];
    return [arrayValuesUsers count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

    return [allKeys objectAtIndex:section];

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

    User *user = [[User alloc] init];

    NSMutableArray *usersInSection = [dictionaryUsers objectForKey:[allKeys objectAtIndex:indexPath.section]];
    user = [usersInSection objectAtIndex:indexPath.row];

    cell.textLabel.text = [NSString stringWithFormat:@"%@, %@", user.lastName, user.firstName];
    cell.detailTextLabel.text = user.email;

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSMutableArray *usersInSection = [dictionaryUsers objectForKey:[allKeys objectAtIndex:indexPath.section]];
    User *usr = [usersInSection objectAtIndex:indexPath.row];

    NSLog(@"user: %@, %@", usr.lastName, usr.firstName);
}



@end

首先,我对使用HelperClass实现一般功能表示赞许。只有当你这样做的时候,至少让它成为一个单身汉,这样你就不必总是打电话:

helper = [[HelperClass alloc] init];
或者,如果您只有像createUser这样的函数,那么这些方法应该是类方法

在查看代码时,我想到了以下两个一般提示:

代码中的分配太多。例如,在TableViewController中,您可以执行以下操作:

users = [[NSMutableArray alloc] init];
users = [helper createUser];
因此,首先分配一个新数组,createUser函数做的第一件事是在内存中分配另一个数组,然后返回。您的第一个分配的内存空间永远不会被使用

当涉及到表视图时,不要使用字典。始终坚持使用数组。字典是不排序的,当遍历字典时,每次可能会得到不同的结果。数组是有序的,objectOfIndex:我将始终返回相同的对象

因此,我调整了您的代码,使其具有一个动态的tableView,将您的用户按城市划分为不同的部分,并按字母顺序进行排序。(我想这就是你想要实现的目标)。新代码不是完全干净的。例如,您可以尝试在任何地方使用NSArray而不是NSMutableArray来节省一些内存

您的用户.h未被触动

这是新的Helper类

//  HelperClass.h


#import <Foundation/Foundation.h>

@interface HelperClass : NSObject


+ (HelperClass *)sharedHelperClass;
+ (NSMutableArray *) createUser;
+ (NSMutableArray *) getAllCitiesFromUserArray: (NSMutableArray *)userArray;
+ (NSMutableArray *)getUsersOfUsersArray: (NSMutableArray *)userArray fromCity: (NSString *)city;

@end
新的TableViewController.h

//  TableViewController.h


#import <UIKit/UIKit.h>

@interface TableViewController : UITableViewController

@end

您假设订购了一本词典。不是。使用NSMutableArray作为表数据的主结构更明智。然后,表行可以直接对数组进行索引。(不过,为每一行准备一本字典是一个好办法。)它不应该是一个单例,但所有的方法都应该是我的类方法。你是对的,我编辑了我的答案,并将所有内容都放在类方法中。我仍然保留了singleton实现,因为他没有在问题中说明HelperClassis中是否发生了其他事情。我是那些认为singleton是反模式的人之一,如果可能的话,应该避免使用。非常感谢你的好建议。这似乎是一个很好的方法来处理helperClass作为单例和安全内存。为了避免字典中不同顺序的问题,我在使用字典键之前对它们进行了排序。
helper = [[HelperClass alloc] init];
users = [[NSMutableArray alloc] init];
users = [helper createUser];
//  HelperClass.h


#import <Foundation/Foundation.h>

@interface HelperClass : NSObject


+ (HelperClass *)sharedHelperClass;
+ (NSMutableArray *) createUser;
+ (NSMutableArray *) getAllCitiesFromUserArray: (NSMutableArray *)userArray;
+ (NSMutableArray *)getUsersOfUsersArray: (NSMutableArray *)userArray fromCity: (NSString *)city;

@end
 //  HelperClass.m


#import "HelperClass.h"
#import "User.h"

@implementation HelperClass


+ (HelperClass *)sharedHelperClass
{

    //This returns always the same object of HelperClass
    static dispatch_once_t pred;
    static HelperClass *_sharedHelperClass = nil;
    dispatch_once(&pred, ^{ _sharedHelperClass = [[self alloc] init]; });
    return _sharedHelperClass;
}


- (id)init{
    self = [super init];
    if (!self) {
        return nil;
    }
    return self;
}


+ (NSMutableArray *) createUser
{
    NSMutableArray *userArray = [[NSMutableArray alloc] init];

    User *user1 = [[User alloc] init];
    user1.firstName = @"Donald";
    user1.lastName = @"Duck";
    user1.email = @"donald_duck@disney.com";
    user1.city = @"Entenhausen";

    User *user2 = [[User alloc] init];
    user2.firstName = @"Micky";
    user2.lastName = @"Maus";
    user2.email = @"micky@disney.com";
    user2.city = @"Entenhausen";

    User *user3 = [[User alloc] init];
    user3.firstName = @"Daisy";
    user3.lastName = @"Duck";
    user3.email = @"daisy_duck@disney.com";
    user3.city = @"Frankfurt";

    User *user4 = [[User alloc] init];
    user4.firstName = @"Goofy";
    user4.lastName = @"Goof";
    user4.email = @"goofy@disney.com";
    user4.city = @"Berlin";

    User *user5 = [[User alloc] init];
    user5.firstName = @"Some";
    user5.lastName = @"Body";
    user5.email = @"somebody@disney.com";
    user5.city = @"Somewhere";

    User *user6 = [[User alloc] init];
    user6.firstName = @"Dagobert";
    user6.lastName = @"Duck";
    user6.email = @"dagobert@disney.com";
    user6.city = @"Mainz";

    [userArray addObject:user1];
    [userArray addObject:user2];
    [userArray addObject:user3];
    [userArray addObject:user4];
    [userArray addObject:user5];
    [userArray addObject:user6];

    return userArray;

}


+ (NSMutableArray *) getAllCitiesFromUserArray: (NSMutableArray *)userArray{

    NSMutableArray *cityArray = [[NSMutableArray alloc] init];

    for (User *user in userArray) {
        if (![cityArray containsObject: user.city]){
            [cityArray addObject:user.city];
        }
    }

    //Sort the city array alphabetically (localizedCaseInsensitiveCompare even regards Umlaute)
    [cityArray sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

    return cityArray;
}

+ (NSMutableArray *)getUsersOfUsersArray: (NSMutableArray *)userArray fromCity: (NSString *)city{


    NSMutableArray *usersOfCityArray = [[NSMutableArray alloc] init];


    for (User *user in userArray) {
        if ([user.city isEqualToString:city]){
            [usersOfCityArray addObject:user];
        }
    }


    //Sort the array of custom objects by key lastName 
    NSSortDescriptor *sortDescriptor =
    [NSSortDescriptor sortDescriptorWithKey:@"lastName"
                                  ascending:YES
                                   selector:@selector(localizedCaseInsensitiveCompare:)];
    usersOfCityArray = [[usersOfCityArray sortedArrayUsingDescriptors:@[sortDescriptor]]mutableCopy];
    return usersOfCityArray;

}


@end
//  TableViewController.h


#import <UIKit/UIKit.h>

@interface TableViewController : UITableViewController

@end
//  TableViewController.m


#import "TableViewController.h"
#import "HelperClass.h"
#import "User.h"

@interface TableViewController ()

@property (nonatomic,strong) NSMutableArray *users;
@property (nonatomic,strong) NSMutableArray *sectionHeaders;


@end

@implementation TableViewController

- (void)viewDidLoad
{
    [super viewDidLoad];


    //This gets the Array of Users from the HelperClass class method
    //You could access the HelperClass Singleton with [HelperClass sharedHelperClass], but this is not needed in this case.

    self.users = [HelperClass createUser];
    self.sectionHeaders = [HelperClass getAllCitiesFromUserArray:self.users];



}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return [self.sectionHeaders count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    //Get the current section city
    NSString *city = [self.sectionHeaders objectAtIndex:section];
    NSMutableArray *sectionUsers =[HelperClass getUsersOfUsersArray:self.users fromCity:city];

    return sectionUsers.count;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {

    return [self.sectionHeaders objectAtIndex:section];

}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }


    //Get the current section city
    NSString *city = [self.sectionHeaders objectAtIndex:indexPath.section];
    //Get users for the current city
    NSMutableArray *sectionUsers =[HelperClass getUsersOfUsersArray:self.users fromCity:city];
    //Get the user for the current cell
    User *user = [sectionUsers objectAtIndex:indexPath.row];

    cell.textLabel.text = [NSString stringWithFormat:@"%@, %@", user.lastName, user.firstName];
    cell.detailTextLabel.text = user.email;

    return cell;
}



#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //Get the current section city
    NSString *city = [self.sectionHeaders objectAtIndex:indexPath.section];
    //Get users for the current city
    NSMutableArray *sectionUsers =[HelperClass getUsersOfUsersArray:self.users fromCity:city];
    //Get the user for the current cell
    User *user = [sectionUsers objectAtIndex:indexPath.row];

    NSLog(@"user: %@, %@", user.lastName, user.firstName);

}


@end