странное поведение drawRect на более быстрых устройствах - PullRequest
0 голосов
/ 20 марта 2012

Хорошо, у меня есть массив фиктивных объектов, содержащих свойство cgpath. Это называется свойством darkPathArray в моем UIView.

Когда я рисовал их один за другим, я обнаружил интересную вещь. Я получил EXC_BAD_ACCESS на CGContextAddPath(context,ppath.path); (ppath.path выбрасывает это) при работе на iOS 5 сим / устройство. Но когда я ставлю вызов NSLog перед CGContextAddPath, он работает правильно. И это потому, что это значительно замедляется.

Так что проблема в частоте -drawRect вызовов. Это нормально, я могу притворяться, пока не сделаю, но профессионал работает не так.

Поэтому я спрашиваю, почему это происходит?

-(void)drawRect:(CGRect)r
{
    // Get the graphics context and clear it
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, self.bounds);

    [[UIColor whiteColor] set];
    UIRectFill ([self bounds]);

    // Draw every single section as a path
    for (ShopSection *section in self.shopSectionsArray) {
        // Draw the walls
        [section.darkColor setFill];

        for (MMPath *ppath in section.darkPathArray) {
            CGContextAddPath(context,ppath.path);
            CGContextDrawPath(context, kCGPathFill);
        }
    }
}

Edit: ARC включен

MMPath не меняются

EXC_BAD_ACCESS отвечает на неверный объект раздела / не знаю, почему (они надежно хранятся в массиве)

Superview: UIScrollView Слой: CATiledLayer

Проблема с плохим доступом возникает, когда содержимое быстро перерисовывается - на быстром устройстве / симуляторе или при дикой прокрутке и масштабировании.

Edit2: Я думаю, я понял! Проблема в том, что CATiledLayer рисует на фоновых потоках, поэтому он как-то ловит хвост У кого-нибудь есть идеи, как это исправить? Каков наилучший подход для этого? Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 20 марта 2012

Этот цикл неверен:

for (MMPath *ppath in section.darkPathArray) {
    CGContextAddPath(context,ppath.path);
    CGContextDrawPath(context, kCGPathFill);
}

CGContextAddPath() добавляет к «текущему пути». CGContextDrawPath рисует «текущий путь». Таким образом, вы продолжаете расширять путь, затем перерисовываете все. Вы имеете в виду это:

for (ShopSection *section in self.shopSectionsArray) {

    // Draw the walls
    [section.darkColor setFill];

    for (MMPath *ppath in section.darkPathArray) {
        CGContextAddPath(context,ppath.path);
    }
}
CGContextDrawPath(context, kCGPathFill);
0 голосов
/ 24 марта 2012

Я наконец передумал и использовал CAShapeLayer вместо моего MMPath (NSObject со свойством CGPath). Затем, используя CGRectIntersectsRect, мне удалось избавиться от этой ошибки многопоточности. Это также означает оптимизацию, поскольку в каждом прямоугольнике нарисованы только соответствующие фигуры.

Так вот как должны быть нарисованы несколько фигур в CATiledLayer:

-(void)drawRect:(CGRect)rect
{
// Get the graphics context and clear it
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClearRect(context, self.bounds);

[[UIColor whiteColor] set];
UIRectFill ([self bounds]);

// Draw every single section as a path
for (ShopSection *section in self.shopSectionsArray) {

    CAShapeLayer *s = section.wallsShapeLayer;
    // Draw the walls
    if ( CGRectIntersectsRect(rect, s.frame ) )
    {
        // Rasterising before rendering enhances the performance a bit
        s.shouldRasterize = YES;
        [s renderInContext:context];
    }
}
}
...