页面控制器

发布于 2024-08-10 05:38:31 字数 1900 浏览 5 评论 0原文

我在从数组中删除未使用的页面时遇到问题:

NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < [descriptionsList count]; i++) {
        [controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];

我正在添加对象:

- (void)loadScrollViewWithPage:(int)page {
    if (page < 0) return;
    if (page >= [descriptionsList count]) return;
    // replace the placeholder if necessary
    DetailsView *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null]) {
        controller = [[DetailsView alloc] initWithElement:[descriptionsList objectAtIndex:page]
                                                 andFrame:CGRectMake(320*page, 0, 320, 420)];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
    }

    // add the controller's view to the scroll view
    if (nil == controller.superview) {
        [scrollView addSubview:controller];
    }
}

并且我正在使用它来删除和创建页面:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    pageControlUsed = NO;

    //load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
    for (unsigned i = 0; i < [descriptionsList count]; i++) {
        if (i < pageController.currentPage - 1 || i > pageController.currentPage + 1) {
            if ([viewControllers objectAtIndex:i] != nil) {
                [[viewControllers objectAtIndex:i] release];
                [viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
            }
        }
        else {
            [self loadScrollViewWithPage:i];
        }
    }
}

当我想查看第 3 页时,我的应用程序崩溃了。关于如何应该如何进行的任何建议这可怎么办?谢谢。

I have a problem with removing unused pages from an array:

NSMutableArray *controllers = [[NSMutableArray alloc] init];
for (unsigned i = 0; i < [descriptionsList count]; i++) {
        [controllers addObject:[NSNull null]];
}
self.viewControllers = controllers;
[controllers release];
[self loadScrollViewWithPage:0];
[self loadScrollViewWithPage:1];

i'm adding objects with:

- (void)loadScrollViewWithPage:(int)page {
    if (page < 0) return;
    if (page >= [descriptionsList count]) return;
    // replace the placeholder if necessary
    DetailsView *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null]) {
        controller = [[DetailsView alloc] initWithElement:[descriptionsList objectAtIndex:page]
                                                 andFrame:CGRectMake(320*page, 0, 320, 420)];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
    }

    // add the controller's view to the scroll view
    if (nil == controller.superview) {
        [scrollView addSubview:controller];
    }
}

and i'm using this to remove and create pages:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    pageControlUsed = NO;

    //load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
    for (unsigned i = 0; i < [descriptionsList count]; i++) {
        if (i < pageController.currentPage - 1 || i > pageController.currentPage + 1) {
            if ([viewControllers objectAtIndex:i] != nil) {
                [[viewControllers objectAtIndex:i] release];
                [viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
            }
        }
        else {
            [self loadScrollViewWithPage:i];
        }
    }
}

My app is crashing big time when i want to view page 3. Any advice on how should this be done? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

芯好空 2024-08-17 05:38:31

有几个问题:

  • NSArrays 不能存储“nil”对象,所以你对 != nil 的检查总是会成功,所以你不需要它
  • 你绝对不应该释放数组中的对象;您没有相应的 -retain 消息,无论如何,数组都会自动保留放入其中的对象,并在它们被删除时释放它们,
  • 您的命名法有点令人困惑。您有一个名为 viewControllers 的数组和一个名为控制器的对象,但它们似乎都是视图(因为您正在 initWithFrame'ing 它们。

A couple of problems:

  • NSArrays can't store 'nil' objects, so your check for != nil will always succeed, so you don't need it
  • You definitely should not be releasing the object in the array; You don't have a corresponding -retain message, and regardless, the array will automatically retain objects put into it, and release them when they're removed
  • your nomenclature is a little confusing. You have an array called viewControllers, and an objected called controller, but these both appear to be views (since you're initWithFrame'ing them.
四叶草在未来唯美盛开 2024-08-17 05:38:31

此行:

if ([viewControllers objectAtIndex:i] != nil)

将始终评估为 TRUE,因为该数组填充了 NSNULL 对象,而这些对象的评估结果不为 nil。即使索引处存储了视图,该块也会执行。此块将使用 NSNull 对象填充整个数组,从而清除所有视图。对该视图的任何后续调用都将崩溃。

我认为你这里的设计很糟糕。您不应该将视图放入数组中。相反,您需要将数据放入数组中,然后根据在任何给定时间应显示的数据来填充可重用视图。看看“UITable”如何通过可重用的“UITableViewCells”显示自身。

This line:

if ([viewControllers objectAtIndex:i] != nil)

will always evaluate as TRUE because the array is populated with NSNULL objects which do not evaluate to nil. The block executes even when there is a view stored at index. This block will populate your entire array with NSNull objects, wiping out all your views. Any subsequent call to the view will crash.

I think you've got a bad design here. You shouldn't be putting views into an Array. Instead, you need to have your data in an array and then populate reusable views based on what data should be displayed at any given time. Look at how 'UITable' displays itself with reusable 'UITableViewCells'.

一袭水袖舞倾城 2024-08-17 05:38:31

事实上,这种延迟加载的方法是我从一本好书中得到的,但示例具有非常非常简单的视图,并且没有释放它们。页面初始化是在scrollViewDidScroll方法中进行的,这在设备上完全混乱了我的内容:一张照片和两个文本。使用的内存使我的应用程序崩溃,这就是为什么我只想保持仅加载 3 个页面。这是更新后的代码,但我无法释放该对象也无法从视图中删除,因此我得到了重复项。

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    for (unsigned i = 0; i < [descriptionsList count]; i++) {
        if (i < pageController.currentPage - 1 || i > pageController.currentPage + 1) {
            DetailsView *controller = [viewControllers objectAtIndex:i];
            if ((NSNull *)controller != [NSNull null]) {
                if (nil != controller.superview) {
                    NSLog(@"remove from superview %d", i);
                    //[controller.superview removeFromSuperview];
                }
                [viewControllers removeObjectAtIndex:i];
                [viewControllers insertObject:[NSNull null] atIndex:i];
                //[viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
            }
        }
        else {
            NSLog(@"allocating %d", i);
            [self loadScrollViewWithPage:i];
        }
    }
}

那么,如果我只使用 2 个可重复使用的视图,我是否能够实时创建视图而不闪烁?我看过一个有 2 个视图的示例,但说内容必须存在,而且我不确定在内存中保留大约 15 个 png 有多好。

This approach with lazy loading i've got it from a good book in fact, but the sample was with very very simple views, and without releasing them. The pages initialization was made in the scrollViewDidScroll method, which was a total mess on the device with my content: a photo and 2 texts. And the memory used is crashing my app, that's why i want to keep loaded only 3 pages. Here's the updated code, but i can't release the object nor remove from view, so i get duplicates.

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

    for (unsigned i = 0; i < [descriptionsList count]; i++) {
        if (i < pageController.currentPage - 1 || i > pageController.currentPage + 1) {
            DetailsView *controller = [viewControllers objectAtIndex:i];
            if ((NSNull *)controller != [NSNull null]) {
                if (nil != controller.superview) {
                    NSLog(@"remove from superview %d", i);
                    //[controller.superview removeFromSuperview];
                }
                [viewControllers removeObjectAtIndex:i];
                [viewControllers insertObject:[NSNull null] atIndex:i];
                //[viewControllers replaceObjectAtIndex:i withObject:[NSNull null]];
            }
        }
        else {
            NSLog(@"allocating %d", i);
            [self loadScrollViewWithPage:i];
        }
    }
}

So, will i be able to create my views in real time without flashes if i'm using only 2 reusable views? I've saw a sample with 2 views but said that the content must exist, and i'm not sure how good is to keep in memory about 15 pngs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文