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/

相关文章:

iphone - 如何将可变数组的对象以数组的形式存储到另一个可变数组中。?

objective-c - 为我的应用程序的文档类型注册一个图标

ios - 检索数据后 Collection View 未重新加载

ios - 在iOS中随机显示字符串而不重复它们

ios - 无法从 iPhone 文档目录位置中保存的文件重新加载 UIImage

iphone - 带有收件人显示名称和电子邮件地址的 MFMailComposeViewController

ios - 确定设备方向及其在一个维度上的角度?

ios - 我如何获得这样的 TextField

ios - xcode 5 水平 ScrollView 不工作 (iOS7)

ios - 是否可以在设备方向更改时更改 Controller 内单个 View 的方向?