草庐IT

ios - UIPageViewController 和删除当前 View Controller

coder 2023-09-24 原文

我将 UIPageViewController 设置为通过一些 View Controller 前进和后退。我有一个问题,当 View Controller 添加到 UIPageViewController 时,内存使用量会增加,直到编译器给我 Received memory warning 然后应用程序运行太慢,直到应用程序清空内存再次正常工作。如何在不增加内存的情况下浏览 View Controller ?或更好地说当新添加时如何删除当前 View Controller 。这是我的代码:

// Create the page view controller.
self.pageViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"PageViewController"];
self.pageViewController.dataSource = self;


//disabling tap and swipe guesture
for (UIGestureRecognizer *recognizer in self.pageViewController.gestureRecognizers) {
    recognizer.enabled = NO;
}


// Instantiate the first view controller.
UIViewController *startingViewController = [self viewControllerAtIndex:0];

[self.pageViewController setViewControllers:@[startingViewController]
                                  direction:UIPageViewControllerNavigationDirectionForward
                                   animated:NO
                                 completion:^(BOOL finished) {
                                     // Completion code
                                 }];

// Add the page view controller to this root view controller.
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
[self.pageViewController didMoveToParentViewController:self];

前进和后退 Action :

- (void)goToPreviousContentViewController
{

    // Get index of current view controller
    UIViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
    NSString *vcRestorationID = currentViewController.restorationIdentifier;
    NSUInteger index = [self.contentPageRestorationIDs indexOfObject:vcRestorationID];

    UIViewController *previousViewController = [self viewControllerAtIndex:index - 1];



    [self.pageViewController setViewControllers:@[previousViewController]
                                      direction:UIPageViewControllerNavigationDirectionReverse
                                       animated:NO
                                     completion:^(BOOL finished) {
                                         // Completion code
                                     }];
}

更多代码:

#pragma mark - UIPageViewControllerDataSource
- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
    return self.contentPageRestorationIDs.count;
}





- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSString *vcRestorationID = viewController.restorationIdentifier;
    NSUInteger index = [self.contentPageRestorationIDs indexOfObject:vcRestorationID];

    if (index == 0) {
        return nil;
    }

    return [self viewControllerAtIndex:index - 1];
}




- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
    NSString *vcRestorationID = viewController.restorationIdentifier;
    NSUInteger index = [self.contentPageRestorationIDs indexOfObject:vcRestorationID];

    if (index == self.contentPageRestorationIDs.count - 1) {
        return nil;
    }

    return [self viewControllerAtIndex:index + 1];
}






#pragma mark - Private Methods
- (UIViewController *)viewControllerAtIndex:(NSUInteger)index
{
    // Only process a valid index request.
    if (index >= self.contentPageRestorationIDs.count) {
        return nil;
    }

    // Create a new view controller.
    BaseContentViewController *contentViewController = (BaseContentViewController *)[self.storyboard instantiateViewControllerWithIdentifier:self.contentPageRestorationIDs[index]];

    // Set any data needed by the VC here
    contentViewController.rootViewController = self;

    return contentViewController;
}

最佳答案

回答您的问题

  1. “如何在不增加内存的情况下浏览 View Controller ?”:

    你真的不能那样做。当您加载一个新的 View Controller 时,它将加载所有 View ,并且 View Controller 存储在内存中。您无法加载和显示不在内存中的 View Controller 。

  2. “如何在添加新 View Controller 时删除当前 View Controller ”:

    你不应该那样做。空 View Controller 不会占用大量内存,您可以轻松地在导航堆栈中拥有 20 多个 View Controller 而不会出现任何内存问题。虽然可以实现这样的东西,但它需要大量的工作,并且不能解决问题的根源。

那问题是什么?

你有一个内存管理问题。这不是由您发布的代码引起的,看起来不错。问题一定出在您代码的另一部分。

有两种常见情况可能会导致内存管理问题:

  1. 保留周期: 保留循环本质上是两个对象相互保留。这违反了对象所有权的标准规则,使两个对象都没有释放另一个对象的权限,从而导致内存泄漏(数字是保留计数):

  2. 不必要的缓存:如果您要下载大量不同的图像并缓存它们,那不是缓存的理想用例。缓存是存储经常访问的对象的理想选择。如果您不经常访问这些图像或收到 didReceiveMemoryWarning 消息,则应释放这些对象。

如何调试内存问题

要做的第一件也是最简单的事情就是覆盖 View Controller 的 dealloc 方法。重写 viewcontroller 上的 dealloc 方法将有助于确保 viewcontroller 在您期望的时候被释放。

-(void)dealloc {
    NSLog(@"viewcontroller is being deallocated");
 }

如果这没有帮助,您可以尝试隔离问题并使用 Xcode Instruments 对其进行调试。 This这篇文章对您来说可能是一个好的开始。

关于ios - UIPageViewController 和删除当前 View Controller ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32871462/

有关ios - UIPageViewController 和删除当前 View Controller的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  3. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  4. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  7. ruby-on-rails - 标准化文件名的字符串,删除重音和特殊字符 - 2

    我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin

  8. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. ruby - 如何找到调用当前方法的方法 - 2

    如何找到调用此方法的位置?defto_xml(options={})binding.pryoptions=options.to_hifoptions&&options.respond_to?(:to_h)serializable_hash(options).to_xml(options)end 最佳答案 键入caller。这将返回当前调用堆栈。文档:Kernel#caller.例子[0]%rspecspec10/16|===================================================62=====

  10. ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序 - 2

    我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于

随机推荐