Большой UIScrollView с перелистыванием страницы иногда падает - PullRequest
0 голосов
/ 07 февраля 2011

У меня есть представление UIScroll, которое, во-первых, немного странно, потому что вы прокручиваете до конца, а затем переворачиваете страницу, и вы также можете вернуться назад, но это именно то, чего хотел клиент. По какой-то причине он иногда падает (чаще на реальном iPad) и делает это без журнала аварий. У меня есть чувство, что это должно быть связано с памятью. Есть ли способ предотвратить сбой? Спасибо.

#import "viewBookVC.h"
#import "switchVC.h"
#import "switchExVC.h"
#import "mainMenuAppDelegate.h"
#import "exGlobal.h"

@implementation ViewBookVC

UIScrollView *scroll;

UIButton *prevPageButton;
UIButton *nextPageButton;

UIImage *scrollImage;

UIImageView *BGview2;

NSMutableArray *BGList;

NSMutableArray *pagingEnabledArr;

int currentPage = 0;

int maxPages = 0;

// used to put a delay on the previous page touch detection
int prevNextPageDetectDelay = 45;

int prevNextPageDetectDelayCounter = 0;

int nextContentOffsetX; 



- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {

        currentPage = 0;

        maxPages = 0;

        prevNextPageDetectDelayCounter = 0;

        mainMenuAppDelegate *del = (mainMenuAppDelegate *)[[UIApplication sharedApplication] delegate];

        // page list
        BGList = [[NSMutableArray alloc] init];

        for(int i = 0; i < 31; i++) {
            NSString *img = [NSString stringWithFormat:@"Viewbook_%d.png", i];
            [BGList addObject:img];
        }


        maxPages = [BGList count];


        // scrolling rules for paging being enabled

        pagingEnabledArr = [[NSMutableArray alloc] init];
        [pagingEnabledArr addObject:@"YES"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"YES"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"YES"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"YES"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"NO"];
        [pagingEnabledArr addObject:@"YES"];
        [pagingEnabledArr addObject:@"YES"];


        timer_checkScrollPos = [[NSTimer scheduledTimerWithTimeInterval:.005
                                                                 target:self
                                                               selector:@selector(onTimer_checkScrollPos:)
                                                               userInfo:nil
                                                                repeats:YES] retain];

        /////////////
        //         //
        // SCROLL  //
        //         //
        /////////////

        //scroll view
        CGRect scrollContainer = CGRectMake(0, 0, 1024, 768);
        scroll = [[UIScrollView alloc] initWithFrame:scrollContainer];
        [scroll setBackgroundColor:[UIColor blackColor]];
        scroll.contentSize = CGSizeMake(1024, 722);

        scroll.showsHorizontalScrollIndicator = YES;
        scroll.bounces = NO;

        scroll.pagingEnabled = YES;

        [self addSubview:scroll];

        // get scroll offset
        NSLog(@"cOffset(A): %f", scroll.contentOffset.x);


        //image to use in scroll
        scrollImage = [UIImage imageNamed:@"Viewbook_0.png"];
        BGview2 = [[UIImageView alloc] initWithImage:(UIImage *)scrollImage];
        BGview2.frame = CGRectMake(0, 23, 1024, 722);


        [scroll addSubview:BGview2];


        //back button [prev button height was compensated for this button to work]

        CGRect backBTNFrame = CGRectMake(10, 30, 140, 52); 
        UIButton * viewbook_backButton = [[UIButton alloc] init];
        viewbook_backButton.frame = backBTNFrame;
        UIImage *viewbook_backButtonIMG = [UIImage imageNamed:@"SHIP_button_back.png"];
        [viewbook_backButton setImage:viewbook_backButtonIMG forState:UIControlStateNormal];
        viewbook_backButton.backgroundColor = [UIColor clearColor];
        [self addSubview:viewbook_backButton];

        [viewbook_backButton addTarget:self 
                                action:@selector(kill_timers)
                      forControlEvents:UIControlEventTouchUpInside];    

        [viewbook_backButton addTarget:del.switchVC 
                                action:@selector(gotoMain)
                      forControlEvents:UIControlEventTouchUpInside];    


        [viewbook_backButton release];





        //prev button
        CGRect prevPageButtonFrame = CGRectMake(0, 70, 312, 698);
        prevPageButton = [[UIButton alloc] init];
        prevPageButton.frame = prevPageButtonFrame;
        prevPageButton.backgroundColor = [UIColor clearColor];
        [self addSubview:prevPageButton];

        [prevPageButton addTarget:self 
                           action:@selector(prevPage:)
                 forControlEvents:UIControlEventTouchUpInside]; 


        //next button
        CGRect nextPageButtonFrame = CGRectMake(712, 0, 312, 768);
        nextPageButton = [[UIButton alloc] init];
        nextPageButton.frame = nextPageButtonFrame;
        nextPageButton.backgroundColor = [UIColor clearColor];
        [self addSubview:nextPageButton];

        [nextPageButton addTarget:self 
                           action:@selector(nextPage:)
                 forControlEvents:UIControlEventTouchUpInside]; 



    }
    return self;
}   


-(void) onTimer_checkScrollPos:(NSTimer*)timer {

    if(currentPage!=0){
        nextContentOffsetX = 750;
    }else{
        nextContentOffsetX = 0;
    }

    //NSLog(@"cOffset(A): %f", scroll.contentOffset.x);
    if(scroll.contentOffset.x >= nextContentOffsetX){
        nextPageButton.hidden = NO;
    }else{
        nextPageButton.hidden = YES;
    }

    if(scroll.contentOffset.x <= 274){
        prevPageButton.hidden = NO;
    }else{
        prevPageButton.hidden = YES;
    }

    prevNextPageDetectDelayCounter += 1;
}


- (void)nextPage:(id)sender {

    if(currentPage!=0){
        nextContentOffsetX = 750;
    }else{
        nextContentOffsetX = 0;
    }

    if(scroll.contentOffset.x >= nextContentOffsetX & prevNextPageDetectDelayCounter>=prevNextPageDetectDelay){

        prevNextPageDetectDelayCounter = 0;

        currentPage+=1;

        if(currentPage >= maxPages){
            currentPage = 0;
        }

        if(currentPage!=0){
            scroll.contentSize = CGSizeMake(2048, 722);
            BGview2.frame = CGRectMake(0, 23, 2048, 722);
        }else{
            scroll.contentSize = CGSizeMake(1024, 722);
            BGview2.frame = CGRectMake(0, 23, 1024, 722);           
        }

        [UIView beginAnimations:@"flipping view" context:nil];
        [UIView setAnimationDuration:0.8];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp
                               forView:scroll
                                 cache:YES];
        [scroll setHidden:NO];
        [UIView commitAnimations];

        if([pagingEnabledArr objectAtIndex:currentPage]==@"YES"){
            scroll.pagingEnabled = YES;
        }else{
            scroll.pagingEnabled = NO;
        }


        BGview2.image = [UIImage imageNamed:[BGList objectAtIndex:currentPage]];

        // set scroll offset
        [scroll setContentOffset:CGPointMake(0,0) animated:NO];

    }
}

- (void)prevPage:(id)sender {
    if(scroll.contentOffset.x <= 274 & prevNextPageDetectDelayCounter>=prevNextPageDetectDelay){

        prevNextPageDetectDelayCounter = 0;

        currentPage-=1;

        if(currentPage < 0){
            currentPage = maxPages-1;
        }

        if(currentPage!=0){
            scroll.contentSize = CGSizeMake(2048, 722);
            BGview2.frame = CGRectMake(0, 23, 2048, 722);
        }else{
            scroll.contentSize = CGSizeMake(1024, 722);
            BGview2.frame = CGRectMake(0, 23, 1024, 722);           
        }

        [UIView beginAnimations:@"flipping view" context:nil];
        [UIView setAnimationDuration:0.8];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        [UIView setAnimationTransition:UIViewAnimationTransitionCurlDown
                               forView:scroll
                                 cache:YES];
        [scroll setHidden:NO];
        [UIView commitAnimations];

        if([pagingEnabledArr objectAtIndex:currentPage]==@"YES"){
            scroll.pagingEnabled = YES;
        }else{
            scroll.pagingEnabled = NO;
        }

        BGview2.image = [UIImage imageNamed:[BGList objectAtIndex:currentPage]];

        // set scroll offset
        [scroll setContentOffset:CGPointMake(0,0) animated:NO];

    }
}

-(void) kill_timers{
    NSLog(@"kill viewbook timer");

    [timer_checkScrollPos invalidate];
    timer_checkScrollPos = nil; 

}

- (void)dealloc {

    [scroll release];

    [BGview2 release];

    [BGList release];

    [pagingEnabledArr release];

    [prevPageButton release];
    [nextPageButton release];

    [timer_checkScrollPos invalidate];
    [timer_checkScrollPos release];

    [super dealloc];
}

@end

1 Ответ

0 голосов
/ 07 февраля 2011

Это похоже на проблему с управлением памятью.Я подозреваю, что вы загружаете все содержимое в память, хотя вы одновременно отображаете только одну или две страницы.Я предлагаю использовать Core Data или XML для загрузки только тех данных, которые вам абсолютно необходимы в любой момент времени.

Поскольку устройство менее стабильно, чем симулятор, следует помнить, что симулятор не эмулятор.Симулятор использует память вашего Mac и не имеет ограничений памяти вашего iPad.

Для отладки у вас есть несколько вариантов:

  • Попробуйте подключить iPad к вашему Mac и посмотреть консоль (Cmd + Shift + R).Вы увидите предупреждение, когда ваше приложение получит предупреждение памяти.За уровнем 1 часто следует уровень 2, за которым часто следует сбой.Это может помочь обосновать существование существующей проблемы.

  • Запустите ваше приложение, используя инструмент Allocations Instrument, чтобы отследить, что может заставить приложение выделять столько памяти.Инструмент утечки поможет вам найти утечки памяти.

  • Воспользуйтесь изящной функцией в Xcode, которая называется "Построить и проанализировать".Это очень хорошо для обнаружения утечек памяти.(Построить -> Построить и проанализировать)

Между утечкой памяти и выделением памяти, которую система не должна давать вам, у вас, вероятно, есть причина ваших сбоев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...