带有页面翻转的大型UIScrollView有时会崩溃

时间:2011-02-07 04:25:22

标签: objective-c cocoa-touch uiscrollview

我有一个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 :(得分:0)

这听起来像是内存管理问题。我怀疑您将所有内容加载到内存中,尽管您一次只显示一个或两个页面。我建议使用Core Data或XML仅加载您在任何给定时间绝对需要的数据。

如果设备不如模拟器稳定,您应该注意模拟器模拟器。模拟器使用Mac中的内存,没有iPad的内存限制。

要调试此功能,您有以下几种选择:

  • 尝试将iPad连接到Mac并观看控制台(Cmd + Shift + R)。当您的应用收到内存警告时,您会看到警告。级别1通常后跟级别2,通常后面是崩溃。这可以帮助证实存在的问题。

  • 使用分配工具运行您的应用,以跟踪可能导致应用分配如此多内存的原因。 Leaks仪器将帮助您发现内存泄漏。

  • 利用Xcode中一个名为“构建和分析”的漂亮功能。它很擅长发现内存泄漏。 (构建 - &gt;构建和分析)

在泄漏内存和分配系统没有给你的内存之间,你可能会导致崩溃。