【问题标题】:IOS - Recursive Functions leaves Memory AllocationsIOS - 递归函数离开内存分配
【发布时间】:2015-06-30 22:08:58
【问题描述】:

我有一个测试应用程序,我在这个应用程序中拥有的是通过 PHP 脚本进行的调用,一旦数据返回,就会一次又一次地调用递归调用 PHP 脚本,依此类推:

发生的事情是每次 [Self recusiveForumActivity];被称为我分配了 300kb 的内存,并且当调用此递归方法时内存使用量不断攀升。如果我删除该方法,内存使用将保持稳定。当每次调用递归方法时,我该如何克服这个问题,以便我根本不会丢失内存分配?

这是代码:

//
        //  ViewController.m
        //  Test
        //
        //  Created by trikam patel on 30/06/2015.
        //  Copyright (c) 2015 trikam patel. All rights reserved.
        //

        #import "ViewController.h"

        @interface ViewController ()

        @end

        @implementation ViewController


        -(NSString*)setupPhpCall:(NSString*)requestString :(NSString*)sciptPage{

            //NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:0];
            //[NSURLCache setSharedURLCache:sharedCache];


            NSHTTPURLResponse *urlresponse = nil;
            NSError *error = nil;
            NSString *response = @"";
            NSData *myRequestData = nil;
            NSMutableURLRequest *request = nil;
            NSData *returnData = nil;

            myRequestData = [NSData dataWithBytes: [requestString UTF8String] length: [requestString length]];

            //Create your request string with parameter name as defined in PHP file
            request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: [NSString stringWithFormat: @"http://www.hugt.co.uk/%@", sciptPage]]];
            // set Request Type
            [request setHTTPMethod: @"POST"];
            // Set content-type
            [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"content-type"];
            // Set Request Body
            [request setHTTPBody: myRequestData];
            // Now send a request and get Response
            //NSHTTPURLResponse* urlResponse = nil;
            //NSError *error = nil;

            //if(tmpArray.count == 0){
            returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlresponse error: &error];
            response = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
            //}
            // Log Response
            urlresponse = nil;
            error = nil;
            myRequestData = nil;
            request = nil;
            returnData = nil;

            //NSLog(@"%@",response);/****/
            //[sharedCache removeAllCachedResponses];
            if(response != nil){

            return response;
            }

            return nil;
        }

        -(void)recurseForumActivity{
            dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

            dispatch_async(concurrentQueue, ^{


            __block NSString *myRequestStringForum = [NSString stringWithFormat:@"lastDate=%@&threadTitle=%@&threadCountry=%@&threadCategory=%@&threadSubCategory=%@&getData=0",@"",@"", @"", @"", @""];
            __block NSString *responseForum = [self setupPhpCall:myRequestStringForum :@"getThreadRecurse.php"];


            dispatch_async(dispatch_get_main_queue(), ^{

                dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

                dispatch_async(concurrentQueue, ^{

                dispatch_async(dispatch_get_main_queue(), ^{
                    [NSThread sleepForTimeInterval:2.0f];
                    responseForum = @"";
                    myRequestStringForum = @"";
                    [self recurseForumActivity];
                });
                });

            });

            });

        }

        - (void)viewDidLoad {
            [super viewDidLoad];
            [self recurseForumActivity];
            // Do any additional setup after loading the view, typically from a nib.
        }

        - (void)didReceiveMemoryWarning {
            [super didReceiveMemoryWarning];
            // Dispose of any resources that can be recreated.
        }

        @end

【问题讨论】:

    标签: ios objective-c xcode memory-management


    【解决方案1】:

    尝试使用[object performSelector:method] 而不是递归调用。递归函数必须始终具有基本/退出条件,并且您的代码没有任何此类条件。所以你不能在这里进行任何递归调用。

    - (void)recurseForumActivity{
        dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
        dispatch_async(concurrentQueue, ^{
    
            __block NSString *myRequestStringForum = [NSString stringWithFormat:@"lastDate=%@&threadTitle=%@&threadCountry=%@&threadCategory=%@&threadSubCategory=%@&getData=0",@"",@"", @"", @"", @""];
            __block NSString *responseForum = [self setupPhpCall:myRequestStringForum :@"getThreadRecurse.php"];
    
            YourClass * __weak weakSelf = self;
    
            dispatch_async(dispatch_get_main_queue(), ^{
    
                dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
                dispatch_async(concurrentQueue, ^{
    
                    dispatch_async(dispatch_get_main_queue(), ^{
                        responseForum = @"";
                        myRequestStringForum = @"";
                        [weakSelf performSelector:@selector(recurseForumActivity) withObject:nil afterDelay:2.0f];
                    });
                });
    
            });
    
        });
    }
    

    【讨论】:

    • 我仍然分配了 300kb 的内存,如果我使用递归块怎么办?
    • 即使是递归块也不起作用,因为内存仍在分配给 300kb
    • @redoc01: 无论如何都会分配内存,因为调用函数涉及存储返回地址、被调用函数的地址等。您应该检查的是您的应用程序的内存占用量不会持续增加。
    • 这可以解决吗?因为我在这上面花了 3 天时间,我尽我所能。
    • @redoc01:您不必担心会分配 300kb。当新的 300kb 被分配时,你应该担心 300kb 被释放。运行您的应用程序并选择 Xcode 左侧的“调试导航器”选项卡。您可以在那里检查应用程序的内存占用。它不应该继续增加。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 2016-01-04
    • 2014-01-02
    • 1970-01-01
    • 2017-10-28
    • 1970-01-01
    相关资源
    最近更新 更多