簡體   English   中英

iOS:后台運行期間主線程速度變慢

[英]IOS: Main thread slowing down during background operation

我正在使用以下代碼來進行我想成為后台同步的操作,但是當接收到的json大於20個左右記錄時,主線程正在減慢速度甚至停止運行。 此代碼的后台操作有什么問題嗎? 什么可能會阻塞主線程。 感謝您的任何建議。

請注意,在performSelectorOnMainThread下面有一條注釋行,其中應用程序處理了我收到的已更改為另一個后台線程的JSON,但此更改似乎無濟於事。

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //1
#define kProductsURL [NSURL URLWithString: @"http://~/getproducts.php"]

//in viewDidLoad
if(hasInternet==YES && [loggedIntoServer isEqual:@1]) {

        dispatch_async(kBgQueue, ^{
            NSData* data = [NSData dataWithContentsOfURL: kProductsURL];
              //previous line grabed data from api.
            if (data) {
         //   [self performSelectorOnMainThread:@selector(fetchData:) withObject:data waitUntilDone:YES];//no longer doing this on main thread
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    [self fetchData:data];
                });

                }
        });
              ;
    } //close hasInternet, logged into server.



  - (void)fetchData:(NSData *)jsonFeed {
    NSError* error;
    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:jsonFeed
                                                         options:kNilOptions
                                                           error:&error];
    NSMutableArray* latestProducts = [[NSMutableArray alloc] init];
    //this is specific to format of JSON
    if (![[json objectForKey:@“products"] isKindOfClass:[NSNull class]]) {
            latestProducts = [[json objectForKey:@“products"]mutableCopy];
    getProducts = latestProducts;
    int size = [latestProducts count];
    [self.tableView reloadData];
    getProducts = [self convertFeedtoObject:latestProducts];
    [self importAndSaveProducts:getProducts];//this imports and saves
    self.recentlySynced=YES;
     }
}

您無需對同一隊列進行嵌套調用。 另外,您應該在主線程上執行任何UI工作。 有關更多信息,請參閱《 Apple 並發編程指南》。

在您的fetchData方法中,像這樣加載表格。

dispatch_async(dispatch_get_main_queue(), {
    // Your UI work 
    [self.tableView reloadData];

})


 // Remove second dispatch_async call 

 //in viewDidLoad
if(hasInternet==YES && [loggedIntoServer isEqual:@1]) {

        dispatch_async(kBgQueue, ^{
            NSData* data = [NSData dataWithContentsOfURL: kProductsURL];
              //previous line grabed data from api.
            if (data) {
                [self fetchData:data];

                }
        });
              ;
} //close hasInternet, logged into server.

您只是做了多余的事情。 您在后台線程中調度了數據獲取。 但是隨后您也做了[self.tableView reloadData]; 在后台線程中。 這就是為什么您的用戶界面會受到影響的原因。

嘗試這個:

if(hasInternet==YES && [loggedIntoServer isEqual:@1]) 
{
    dispatch_async(kBgQueue, ^
    {
        NSData* data = [NSData dataWithContentsOfURL: kProductsURL];

        if (data) 
        {
              dispatch_async(dispatch_get_main_queue(), ^
              {
                  [self fetchData:data];
              });
        }
    });
}

我所做的是更改了代碼的這一部分:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                    [self fetchData:data];
                });

因為您只應在主線程中對UI進行任何更改。 我的代碼的這一部分正在主線程中完成工作。

dispatch_async(dispatch_get_main_queue(), ^
                  {
                      [self fetchData:data];
                  });

您的原始代碼中有幾個錯誤,請更改為以下內容:

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0) //CHANGE TO BACKGROUND
#define kProductsURL [NSURL URLWithString: @"http://~/getproducts.php"]

//in viewDidLoad
if(hasInternet==YES && [loggedIntoServer isEqual:@1]) {
        dispatch_async(kBgQueue, ^{
            NSData* data = [NSData dataWithContentsOfURL: kProductsURL];
            if (data) {             
                [self fetchData:data];
            }
        });
    } //close hasInternet, logged into server.

將獲取數據更改為以下內容:

- (void)fetchData:(NSData *)jsonFeed {
    NSError* error;
    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:jsonFeed
                                                         options:kNilOptions
                                                           error:&error];

    NSMutableArray* latestProducts = [[NSMutableArray alloc] init];

    //this is specific to format of JSON
    if (![[json objectForKey:@"products"] isKindOfClass:[NSNull class]]) {

        latestProducts = [[json objectForKey:@"products"]mutableCopy];

        getProducts = latestProducts;
        int size = [latestProducts count];

        //Do this on the main thread:
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView reloadData];
        });

        getProducts = [self convertFeedtoObject:latestProducts];
        [self importAndSaveProducts:getProducts];//this imports and saves
        self.recentlySynced=YES;
     }
}

根據表視圖的工作方式以及數據源的類型,您可能希望將重載表視圖行(使用主隊列調度)移動到self.recentSynced = YES下方。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM