NSMutableDictionary顺序在iOS8中不同(与iOS7相反)

NSMutableDictionary顺序在iOS8中不同(与iOS7相反),ios,objective-c,nsmutablearray,nsmutabledictionary,Ios,Objective C,Nsmutablearray,Nsmutabledictionary,在过去几年中(iOS8/XCode 6之前),这段代码生成了一个表,其顺序为 设备名称 燃烧气体分析 安全检查 电器检查 调查结果和完成情况 现在在iOS8/XCode中,6翻转NSMutableDictionary中两个NSMutableArray的顺序,因此输出 燃烧气体分析 安全检查 电器检查 调查结果和完成情况 设备名称 为什么 #import "svServiceVC.h" #import "SingletonID.h" #import "escgasDatabase.h" #

在过去几年中(iOS8/XCode 6之前),这段代码生成了一个表,其顺序为

  • 设备名称
  • 燃烧气体分析
  • 安全检查
  • 电器检查
  • 调查结果和完成情况
现在在iOS8/XCode中,6翻转NSMutableDictionary中两个NSMutableArray的顺序,因此输出

  • 燃烧气体分析
  • 安全检查
  • 电器检查
  • 调查结果和完成情况
  • 设备名称
为什么

#import "svServiceVC.h"
#import "SingletonID.h"
#import "escgasDatabase.h"
#import "FMDBDataAccess.h"

@interface svServiceVC ()
@end

@implementation svServiceVC

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.theTable.delegate = self;
    self.theTable.dataSource =self;
}

- (void)viewWillAppear:(BOOL)animated
{
    [self buildTableData];
    [_theTable reloadData];
}

- (void)buildTableData
{
    anApplianceNamed = 0;
    generalInspectationDone = 0;
    _appliancesDict = [[NSMutableDictionary alloc] init];
    [_appliancesDict setValue:[[NSMutableArray alloc] init] forKey:@"Appliances"];
    [_appliancesDict setValue:[[NSMutableArray alloc] init] forKey:@"Inspection"];

    // snip


    [[_appliancesDict objectForKey:@"Appliances"] addObject:appString1];

    [[_appliancesDict objectForKey:@"Inspection"] addObject:@"Combustion gas analysis"];

    [[_appliancesDict objectForKey:@"Inspection"] addObject:@"Safety checks"];

    [[_appliancesDict objectForKey:@"Inspection"] addObject:@"Appliance checks"];

    [[_appliancesDict objectForKey:@"Inspection"] addObject:@"Findings & Completion"];

    generalInspectationDone = 1;
}


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [_appliancesDict count];
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[_appliancesDict valueForKey:[[_appliancesDict allKeys] objectAtIndex:section]] count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"AppCell";

    UITableViewCell *cell;
    NSArray *versionCompatibility = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];

    if ( 6 <= [[versionCompatibility objectAtIndex:0] intValue] )
    {
        // iOS6 is installed
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    }
    else
    {
        // iOS5 is installed
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier ];
    }


    NSString *appTitle = [[_appliancesDict valueForKey:[[_appliancesDict allKeys] objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];

    cell.textLabel.text = appTitle;

    if (indexPath.section==0)
    {
        // The appliance cells

        if ([cell.textLabel.text hasPrefix:@"Appliance"])
        {
            cell.textLabel.textColor = [UIColor lightGrayColor];
        }
        else
        {
            cell.textLabel.textColor = [UIColor blackColor];
        }



    }
    else
    {

        // The inspection rows

        if (indexPath.row==0)
        {
            //
            if (gasInspection==0)
            {
                cell.textLabel.textColor = [UIColor lightGrayColor];
            }
            else
            {
                cell.textLabel.textColor = [UIColor blackColor];
            }


        }
        else if (indexPath.row==1)
        {
            // * Gas inpsection

            if (safetyChecks==0)
            {
                cell.textLabel.textColor = [UIColor lightGrayColor];
            }
            else
            {
                cell.textLabel.textColor = [UIColor blackColor];
            }


        }
        else if (indexPath.row==2)
        {
            // * Gas inpsection

            if (applianceChecks==0)
            {
                cell.textLabel.textColor = [UIColor lightGrayColor];
            }
            else
            {
                cell.textLabel.textColor = [UIColor blackColor];
            }


        }
        else if (indexPath.row==3)
        {

            if (generalInspectationDone==0)
            {
                //cell.textLabel.textColor = [UIColor lightGrayColor];
                cell.textLabel.textColor = [UIColor blackColor];
            }
            else
            {
                cell.textLabel.textColor = [UIColor blackColor];
            }

        }


    }

    return cell;
}


#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"didSelectRowAtIndexPath:indexpath %li %li",(long)indexPath.section, (long)indexPath.row);

    switch (indexPath.section)
    {
        case 0:

            // Appliances
            [SingletonID sharedSingleton].appliance = @"_1";


            [self performSegueWithIdentifier:@"svApplianceSegue" sender:self];
            break;

        case 1:


            switch (indexPath.row){

            case 0:
                [self goGasAnalysis];
                break;

            case 1:
                [self goSafety];
                break;

            case 2:
                [self goChecks];
                break;

            case 3:
                [self goComplete];
                break;

            default:
                break;

        }


    }

}
#导入“svServiceVC.h”
#导入“SingletonID.h”
#导入“escgasDatabase.h”
#导入“FMDBDataAccess.h”
@接口svServiceVC()
@结束
@svServiceVC的实现
-(无效)viewDidLoad
{
[超级视图下载];
self.theTable.delegate=self;
self.theTable.dataSource=self;
}
-(无效)视图将显示:(BOOL)动画
{
[自建表数据];
[_thetablereloaddata];
}
-(void)buildTableData
{
anapplicancenamed=0;
GeneralInspectionDone=0;
_ApplianceDict=[[NSMutableDictionary alloc]init];
[_appliancedictsetvalue:[[NSMutableArray alloc]init]forKey:@“设备”];
[_appliancedictsetvalue:[[NSMutableArray alloc]init]forKey:@“检查”];
//剪断
[[u appliancedict objectForKey:@“设备”]addObject:appString1];
[[u appliancedict objectForKey:@“检查”]添加对象:@“燃烧气体分析”];
[[u appliancedict objectForKey:@“检查”]添加对象:@“安全检查”];
[[u appliancedict objectForKey:@“检查”]addObject:@“设备检查”];
[[u appliancedict objectForKey:@“检查”]添加对象:@“发现和完成”];
一般检查完成=1;
}
#pragma标记-表视图数据源
-(NSInteger)表格视图中的节数:(UITableView*)表格视图
{
返回[_appliancedictcount];
}
-(NSInteger)表视图:(UITableView*)表视图行数节:(NSInteger)节
{
返回[[[u appliancedict valueForKey:[[u appliancedict allkey]objectAtIndex:section]]count];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
静态NSString*CellIdentifier=@“AppCell”;
UITableViewCell*单元格;
NSArray*versionCompatibility=[[UIDevice currentDevice].systemVersion组件由字符串分离:@“。”;

如果(6字典是无序的。这是一个实现细节。“为什么?”的答案是苹果改变了实现。因为他们知道好的代码永远不会依赖于顺序,所以他们可以自由地这样做


如果您想将密钥按特定顺序存储,可以保留一个单独的数组,其中密钥按您喜欢的顺序存储。

文档中说:

allKeys返回包含字典键的新数组

-(NSArray*)所有钥匙

返回值

包含字典键的新数组,如果字典没有条目,则为空数组

讨论

未定义数组中元素的顺序。

(增加重点)

因此,NSDictionary可以按任何顺序返回密钥。从技术上讲,它可以在您每次调用
allKeys
时随机化密钥顺序,并且仍然履行其合同义务


顺序更改不需要具体原因。如果您想要确定的顺序,请使用选择器:
(或通过比较器)使用
-keyssortedbyvalues,或者自己对
所有键
数组进行排序。

NSString*appTitle=[[u appliancedict valueForKey:[[u appliancedict allKeys]objectAtIndex:indexPath.section]]objectAtIndex:indexath.row];

您正在使用
allKeys
获取“部分”列表,在本例中为“设备”和“检查”。这里的问题是字典没有强制执行其键的顺序。您可以在的文档中看到这一点,因为它明确说明了这一事实

allkey

返回包含字典键的新数组

返回值:包含字典键的新数组,如果字典没有条目,则返回空数组

讨论:未定义数组中元素的顺序


iOS 8中NSDictionary的实现似乎发生了一些变化,影响了密钥的内部排序。因为API从一开始就没有保证固定的排序,所以苹果可以这样做。

这一定是dictionary中的实现变化,但它一直都是,而且仍然是一个天生无序的集合。