iphone - dispatch_async 会降低 UI 和应用程序的速度

标签 iphone objective-c ios xcode multithreading

我正在使用 dispatch_async 进行后台上传。从另一个 Stackoverflow 问题中,我发现 dispatch_asyncPerformSelectorInBackground 更好。但是现在在我调用它之后,用户界面变得非常慢。谁能为此提供解决方案?下面添加了我使用的代码:

__block NSString *someString;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 
                                         (unsigned long)NULL), ^(void) {

  if(someString != nil)
    {
        Class *className = [class sharedObject];
        [className sendContacts];

    }

});

函数代码:

-(void) sendContacts {

    NSURL *url = [NSURL URLWithString:@"myurl"];

    ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
    [request setRequestMethod:@"POST"];

    [request addRequestHeader:@"d" value:[[UIDevice currentDevice] uniqueIdentifier]];

    NSString *sessionKey = [[NSUserDefaults standardUserDefaults]valueForKey:@"UD_Sessionkey"];

    [request addRequestHeader:@"s" value:sessionKey];

    NSData *data=[[self createContactList] dataUsingEncoding: [NSString defaultCStringEncoding] ];

    NSMutableData *x = [[NSMutableData alloc] init]; 
    [x setData:data];

    [request setPostBody:x];

    [request setShouldContinueWhenAppEntersBackground:YES];
    [request setDelegate:self];
    [request setTimeOutSeconds:60];
    [request setDidFinishSelector:@selector(requestFinished:)];
    [request setDidFailSelector:@selector(requestFailed:)];
    [request startAsynchronous];

}


- (void)requestFinished:(ASIHTTPRequest *)requestData
{

    NSLog(@"Response : %@", [requestData responseString]);

    if (self.currentLimit_ > totalCount) {

        //do nothing
    } else {

        [self sendContacts];
    }


}

- (NSString *)createContactList
{

    self.currentLimit_ = self.currentLimit_ + 10;
    self.currentCount_ = self.currentCount_ + 1;

    ABAddressBookRef addressBook = ABAddressBookCreate();
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

    totalCount = nPeople;

    NSMutableString *requestContactsString = [[NSMutableString alloc] init];


    [requestContactsString appendString:@"<list>"];

    for (int i=currentCount; i<self.currentLimit_; i++)
    {
        NSLog(@"Started : %d", i);
        if (self.currentLimit_ > totalCount) {
            break;
        }

        if (i < self.currentLimit_ - 10) {

            continue;
        }

        ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
        CFTypeRef firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
        CFTypeRef lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
        CFTypeRef email = ABRecordCopyValue(ref, kABPersonEmailProperty);
        CFTypeRef phone = ABRecordCopyValue(ref, kABPersonPhoneProperty);

        //requestContactsString = [requestContactsString stringByAppendingFormat:@"<item>"];
        [requestContactsString appendString:@"<item>"];

        if(firstName)
        {
            [requestContactsString appendString:[NSString stringWithFormat:@"<firstname>%@</firstname>", firstName]];

            CFRelease(firstName);
            firstName = nil;
        }
        if(lastName)


            [requestContactsString appendString:[NSString stringWithFormat:@"<lastname>%@</lastname>", lastName]];
            CFRelease(lastName);
            lastName = nil;
        }
        if(email)
        {
            if(ABMultiValueGetCount(email)>0)
            {
                CFTypeRef em = ABMultiValueCopyValueAtIndex(email, 0);

                [requestContactsString appendString:[NSString stringWithFormat:@"<email>%@</email>", em]];

                CFRelease(em);
            }
            CFRelease(email);
            email = nil;
        }
        if(phone)
        {
            if(ABMultiValueGetCount(phone)>0)
            {
                CFTypeRef ph = ABMultiValueCopyValueAtIndex(phone, 0);

                [requestContactsString appendString:[NSString stringWithFormat:@"<phone>%@</phone>", ph]];
                CFRelease(ph);
            }
            CFRelease(phone);
            phone = nil;
        }

        [requestContactsString appendString:@"</item>"];

    }



    if(allPeople)
    {
        CFRelease(allPeople);
        allPeople = nil;
    }
    if(addressBook)
    {
        CFRelease(addressBook);
        addressBook = nil;
    }

    [requestContactsString appendString:@"</list>"];

    NSString *hashedContactsString = [self generateHashedPassword:requestContactsString];

    NSLog(@"Contacts : %@", requestContactsString);

    //contact list has changed
    if(![[[NSUserDefaults standardUserDefaults] valueForKey:@"contacts"] isEqualToString:hashedContactsString])
    {
        return requestContactsString;
    }
    else return nil;
}

最佳答案

可能是自动释放的对象变慢了......必须检查 instruments 工具哪个功能花费更多时间。

//Can you try using autoreleasepool for the threaded function. 
     dispatch_async(yourQueue, ^{
                     @autoreleasepool {
                         //Your code to be run in background
                         dispatch_async(dispatch_get_main_queue(), ^{
                             //Any UI updates
                         });
                     }
                 });

关于iphone - dispatch_async 会降低 UI 和应用程序的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11389167/

相关文章:

ios - 无法使用 gradle 在 iPhone 模拟器中启动 libgdx ios/robovm 构建

iphone - 如何将 UITableView 添加到包含其他对象的父级?

javascript - Phonegap Input 专注于 Mobile Safari

ios - 在方向更改时重新加载 UIPageViewController View

ios - 使用 NSInteger 而不是 int 的好处?

iphone - "EXC_BAD_ACCESS"我该如何解决这个问题?

ios - 如何使用对象映射器 Swift 映射字典数组

iphone - 我必须这样投吗?

objective-c - 如何以编程方式获取 mac os x 上已安装应用程序的列表

ios - Swift:用常量字符串声明常量数组