Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS-不一次分配太多内存_Ios_Memory Management_Uiview - Fatal编程技术网

iOS-不一次分配太多内存

iOS-不一次分配太多内存,ios,memory-management,uiview,Ios,Memory Management,Uiview,试图绕过一些iOS设备上正在发生的崩溃,同时苹果建议“不要造成分配高峰”。如何才能将此代码更改为不同时发生 for (Item *item in self.items) { ItemView *itemView = [[ItemView alloc] initWithFrame:CGRectMake(xPos, kYItemOffsetIphone, kItemWidthIphone, kItemHeightIphone) ]; itemView.delegat

试图绕过一些iOS设备上正在发生的崩溃,同时苹果建议“不要造成分配高峰”。如何才能将此代码更改为不同时发生

for (Item *item in self.items) {
        ItemView *itemView = [[ItemView alloc] initWithFrame:CGRectMake(xPos, kYItemOffsetIphone, kItemWidthIphone, kItemHeightIphone) ];

        itemView.delegate = self;
        [itemView layoutWithData:item]; //this just adds an imageView and button
        [self.scrollView addSubview:itemView];
        xPos += kXItemSpacingIphone;
    }

self.items数组中大约有20个对象,用于构建20个ItemView。再说一次,有没有办法让这段代码不那么“分配密集型”呢?

我个人做了以下几点:

  • 使我的视图控制器成为滚动视图的
    委托
    (如果在代码中执行此操作,则必须修改视图控制器的.h,使其符合
    UIScrollViewDelegate

  • 定义(a)确定滚动视图可见部分的帧的方法;(b) 确定哪些子视图与该可见部分相交;(c) 加载可见的项目,卸载不可见的项目

  • 例如,它可能看起来如下所示:

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        // Determine the frame of the visible portion of the scrollview.
    
        CGRect visibleScrollViewFrame = scrollView.bounds;
        visibleScrollViewFrame.origin = scrollView.contentOffset;
    
        // Now iterate through the various items, remove the ones that are not visible,
        // and show the ones that are.
    
        for (Item *itemObject in self.itemCollection)
        {
            // Determine the frame within the scrollview that the object does (or 
            // should) occupy.
    
            CGRect itemObjectFrame = [self getItemObjectFrame:itemObject];
    
            // see if those two frames intersect
    
            if (CGRectIntersectsRect(visibleScrollViewFrame, itemObjectFrame))
            {
                // If it's visible, then load it (if it's not already).
                // Personally, I have my object have a boolean property that
                // tells me whether it's loaded or not. You can do this any
                // way you want.
    
                if (!itemObject.loaded)
                    [itemObject loadItem];
            }
            else
            {
                // If not, go ahead and unload it (if it's loaded) to conserve memory.
    
                if (itemObject.loaded)
                    [itemObject unloadItem];
            }
        }
    }
    

    这是基本的想法。您当然可以根据应用程序的特定设计优化此逻辑,但我通常是这样做的。

    所有视图是否同时可见?如果没有,您可以推迟创建视图,直到它即将进入屏幕(并且,类似地,您可以在视图离开屏幕时销毁它[只要您以后可以重新创建其当前状态])。这就是
    UITableView
    的工作原理。@KevinBallard是否有样板代码可以用UIScrollView来做这件事?@soleil所以你真正想要的是
    UITableView
    但旋转90度?@Tommy是的,我想你可以这么说。这只是一个图像的滚动视图。@soleil也许集合视图会有所帮助?回答得很好。询问者还可以实现某种可重用的视图数组,这样当项目移出屏幕时,它们就会从视图层次结构中移除并添加到这个可重用的视图数组中。加载新项时,代码可以检查是否已经创建了可重用视图,如果已经创建了,则获取对可重用视图的引用,然后将其从数组中删除。冲洗并重复。这非常类似于
    UITableView
    的实例如何在具有大量视图的很长列表中管理其单元格。@ThuggishNuggets同意。我想保持简单,但你说得很对。(这个出列逻辑可能属于这些
    loadItem
    unloadItem
    方法。)为了获得最佳性能,他可能还想对图像本身进行一些缓存(I subclass
    NSCache
    )。在scrollview的末尾,它会反弹回来,在重新检索图像时会有一点延迟,这很烦人。不过,我还是尽量保持简单。