0

我有这样的方法,并且很难优化它以更好地运行。100 个单位大约需要 1 秒,并且在 和 之间进行 4NSLog(@"Debug2")NSLog(@"Debug3")。在 iPhone 上 2 秒。随着更多的单位,它需要更多。250 个单位和 5 次在 mac 上需要 1.7 秒,在 iphone 上需要 3.2 秒。

我不认为表现在于一个周期内的周期。由于 250 * 5 = 1250,对于计算机来说处理速度不应该太多。

方法思路:

输入:NSMutableArray times - 包含时间 (2012-12-12, 2013-01-19) 等 NSMutableArray objectArray - 包含LogUnit对象。输出:计算视图数组。

主要思想:每个时间的视图,其中包含时间相同的 ObjectArray 中的对象。

我通过显示一小部分对象(参见counted代码和_breakPlease)使其更快,但它仍然不够快。

- (NSMutableArray*) sortViews: (NSMutableArray *)times and:(NSMutableArray *)objectArray
{
    NSLog(@"debug2");
    NSMutableArray *views = [[NSMutableArray alloc] initWithCapacity:times.count];

    NSString *number = [NSString stringWithFormat:@"SortLog%i ",[[NSUserDefaults standardUserDefaults] stringForKey:@"ObjectNumber"].intValue];

    NSString *comp = [[NSUserDefaults standardUserDefaults] stringForKey:number];

    LogUnit *unit;

    int counted = 0;
    for(int x = 0; x != times.count; x++)
    {
        @autoreleasepool {

        UIView *foo = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 400)];   
        foo.backgroundColor = [UIColor clearColor];

        int f = 0;
        int h = 0;

        NSString *attributeName = @"realTime";
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K IN %@", attributeName, [times objectAtIndex:x]];
        // Filter the objectArray by the time, so we don't have to run through all the objects in objectArray, and check if time is right.
        NSArray *filtered  = [objectArray filteredArrayUsingPredicate:predicate];

        for(int i = 0; i != filtered.count; i++)
        {
                unit = [filtered objectAtIndex:i];

                // Filter units by user choice (comp). Like comp = Warnings or comp = Errors and etc.
                if([[unit status] isEqualToString:comp] || [comp isEqualToString:NULL] || comp == NULL)
                {
                     // testing if the unit is correct to use
                    if([unit getEvent] != NULL)
                    {
                    // below is some computation for frames, to get them to proper position
                        unit.view.frame = CGRectMake(unit.view.frame.origin.x, f * unit.view.frame.size.height + 30, unit.view.frame.size.width, unit.view.frame.size.height);
                        [foo addSubview:unit.view];
                        counted++;
                        f++;
                        h = unit.view.frame.size.height * f;
                    }
                }
        }

        UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 30)];
        myLabel.backgroundColor = [UIColor clearColor];
        myLabel.font = [UIFont boldSystemFontOfSize:20];
        myLabel.textColor = [UIColor colorWithRed:88 green:154 blue:251 alpha:1];
        myLabel.textAlignment = UITextAlignmentCenter;
        myLabel.text = [times objectAtIndex:x];
        // Just adding a label with "2012-12-30" or etc on top of the view.    
        [foo addSubview:myLabel];

        foo.frame = CGRectMake(0,0, 320, h + 30 );
        h = 0;
        [views addObject:foo];

        // counting added views for performance, if more than 30, return, and show only small portion of whole units, user has the option to show all the units if he wants to, but that takes a time to load..
        if(counted > 30 && filtered.count != counted)
        {
            if(_breakPlease == false)
            {
                _broken = true;
                break;
            }
        }
       }
    }
    NSLog(@"debug3");
    return views;
}
4

1 回答 1

4

有几件事供您尝试。

首先进行分析:

  • 尝试 Instruments 中的分析器;
  • 如果您对分析器有一些怨恨,那么请尝试获取代码每个部分的中值时间。

现在进行优化:

  • 不要在循环中创建完全相同的对象。尝试创建示例对象,然后重用它们或复制它们;
    • 创建一个示例UIView并将其存档,并在您需要新视图时将其取消存档。将此也应用于UILabel;
    • 虽然我从未使用过它,但有一种方法可以在以后创建NSPredicate并应用一些值。这样你可以重复使用相同的UIPredicate
    • 将您需要的颜色也保存在变量中,而不是询问,UIColor因为我们不知道如何UIColor处理它;
  • 你能短路你的内for循环,即你有最大数量的正确单元吗?

好吧,分析器应该足以让你了解你的瓶颈在哪里,但我也让你有一些想法。

不要忘记在这里报告结果!:)

于 2013-01-31T07:53:37.260 回答