Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone UIActionSheet和Twitter用户名选择_Iphone_Objective C_Ios_Twitter - Fatal编程技术网

Iphone UIActionSheet和Twitter用户名选择

Iphone UIActionSheet和Twitter用户名选择,iphone,objective-c,ios,twitter,Iphone,Objective C,Ios,Twitter,我正在尝试实现一种方法,让用户从他们在iPhone(iOS5及更高版本)上设置的Twitter帐户中进行选择。我可以让用户名出现在UIActionSheet中,但由于某些原因,在调用该方法后,UIActionSheet大约需要5秒钟才能出现 我想可能是因为检索Twitter帐户列表花了一段时间,但在我的日志中,它们会立即出现,所以不是这样 有什么想法吗 - (void)TwitterSwitch { ACAccountStore *accountStore = [[ACAccountSt

我正在尝试实现一种方法,让用户从他们在iPhone(iOS5及更高版本)上设置的Twitter帐户中进行选择。我可以让用户名出现在UIActionSheet中,但由于某些原因,在调用该方法后,UIActionSheet大约需要5秒钟才能出现

我想可能是因为检索Twitter帐户列表花了一段时间,但在我的日志中,它们会立即出现,所以不是这样

有什么想法吗

- (void)TwitterSwitch {
    ACAccountStore *accountStore = [[ACAccountStore alloc] init];

// Create an account type that ensures Twitter accounts are retrieved.
    ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

    NSMutableArray *buttonsArray = [NSMutableArray array];

// Request access from the user to use their Twitter accounts.
    [accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {


       // Get the list of Twitter accounts.
        NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];

       NSLog(@"%@", accountsArray);


       [accountsArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

           [buttonsArray addObject:((ACAccount*)obj).username];
        }];


       NSLog(@"%@", buttonsArray);

        UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
        for( NSString *title in buttonsArray)
            [actionSheet addButtonWithTitle:title];
        [actionSheet addButtonWithTitle:@"Cancel"];
        actionSheet.cancelButtonIndex = actionSheet.numberOfButtons-1;
        [actionSheet showFromTabBar:self.tabBarController.tabBar];
}]; 

}

您始终可以使用多线程来加速任务。以下是您如何做到这一点:

dispatch_queue_t twitterAccounts = dispatch_queue_create("DisplayTwitterAccounts", NULL);
    dispatch_async(twitterAccounts, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
        //Your Code goes here
        });
    });
dispatch_release(twitterAccounts);
注意dispatch_async(dispatch_get_main_queue()):这是因为UIKit调用只能在主线程中发生。(参考:斯坦福CS193P课程幻灯片)


“DisplayTwitterAccounts”只是队列的名称,因此您可以在调试器/控制台中查找它。

您可以始终使用多线程来加速任务。以下是您如何做到这一点:

dispatch_queue_t twitterAccounts = dispatch_queue_create("DisplayTwitterAccounts", NULL);
    dispatch_async(twitterAccounts, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
        //Your Code goes here
        });
    });
dispatch_release(twitterAccounts);
注意dispatch_async(dispatch_get_main_queue()):这是因为UIKit调用只能在主线程中发生。(参考:斯坦福CS193P课程幻灯片)


“DisplayTwitterAccounts”只是队列的名称,因此您可以在调试器/控制台中查找它。

我认为问题可能在于,在requestAccessToAccountsWithType:withCompletionHandler:可以在任意队列上调用该处理程序,并且您正在该处理程序中显示UI元素(操作表)。由于与UI的交互应该只在主线程上完成,这可能是一个问题。我尝试将一些代码移动到另一个方法中,并在主线程上调用它——这要快得多:

- (void)TwitterSwitch {
    ACAccountStore *accountStore = [[ACAccountStore alloc] init];

    // Create an account type that ensures Twitter accounts are retrieved.
    ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];


    // Request access from the user to use their Twitter accounts.
    [accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {


        // Get the list of Twitter accounts.
        NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];

        NSLog(@"%@", accountsArray);
        [self performSelectorOnMainThread:@selector(populateSheetAndShow:) withObject:accountsArray waitUntilDone:NO];
        }];
}

-(void)populateSheetAndShow:(NSArray *) accountsArray {
    NSMutableArray *buttonsArray = [NSMutableArray array];
    [accountsArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

            [buttonsArray addObject:((ACAccount*)obj).username];
        }];


        NSLog(@"%@", buttonsArray);

        UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
        for( NSString *title in buttonsArray)
            [actionSheet addButtonWithTitle:title];
        [actionSheet addButtonWithTitle:@"Cancel"];
        actionSheet.cancelButtonIndex = actionSheet.numberOfButtons-1;
        [actionSheet showInView:self.view];
}

请注意,我更改了显示工作表的方式,因为在我的测试应用程序中,我没有选项卡栏控制器。

我认为问题可能在于,在requestAccessToAccountsWithType:withCompletionHandler:可以在任意队列上调用该处理程序,而您正在该处理程序中显示UI元素(操作表)。由于与UI的交互应该只在主线程上完成,这可能是一个问题。我尝试将一些代码移动到另一个方法中,并在主线程上调用它——这要快得多:

- (void)TwitterSwitch {
    ACAccountStore *accountStore = [[ACAccountStore alloc] init];

    // Create an account type that ensures Twitter accounts are retrieved.
    ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];


    // Request access from the user to use their Twitter accounts.
    [accountStore requestAccessToAccountsWithType:accountType withCompletionHandler:^(BOOL granted, NSError *error) {


        // Get the list of Twitter accounts.
        NSArray *accountsArray = [accountStore accountsWithAccountType:accountType];

        NSLog(@"%@", accountsArray);
        [self performSelectorOnMainThread:@selector(populateSheetAndShow:) withObject:accountsArray waitUntilDone:NO];
        }];
}

-(void)populateSheetAndShow:(NSArray *) accountsArray {
    NSMutableArray *buttonsArray = [NSMutableArray array];
    [accountsArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

            [buttonsArray addObject:((ACAccount*)obj).username];
        }];


        NSLog(@"%@", buttonsArray);

        UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
        for( NSString *title in buttonsArray)
            [actionSheet addButtonWithTitle:title];
        [actionSheet addButtonWithTitle:@"Cancel"];
        actionSheet.cancelButtonIndex = actionSheet.numberOfButtons-1;
        [actionSheet showInView:self.view];
}

请注意,我更改了显示工作表的方式,因为在我的测试应用程序中,我没有选项卡栏控制器。

我将使用哪一行设置
twitterAccounts
变量?我将使用哪一行设置
twitterAccounts
变量?我无法测试这个,但是我认为不需要enumerateObjectsUsingBlock方法或buttonsArray。在for-In循环中,您只需在accounts数组(ACAccount*account-In-accountsArray)中循环,然后添加标题为account.username.addButtonWithTitle的Button,效果非常好,包括您建议使用SingBlock和buttonsArray删除EnumerateObjects。谢谢顺便问一下,我如何将actionSheet数组的大小限制为前5个帐户?我担心,如果一个用户有一大堆Twitter账户,它可能会打乱行动计划。首先,你必须决定“前5个”是什么意思。如果您只想得到前5个,那么只需为in循环添加一个计数器变量,当它达到5时,使用break命令退出循环。我无法测试这一点,但我认为不需要EnumerateObjectsSusingBlock方法或buttonsArray。在for-In循环中,您只需在accounts数组(ACAccount*account-In-accountsArray)中循环,然后添加标题为account.username.addButtonWithTitle的Button,效果非常好,包括您建议使用SingBlock和buttonsArray删除EnumerateObjects。谢谢顺便问一下,我如何将actionSheet数组的大小限制为前5个帐户?我担心,如果一个用户有一大堆Twitter账户,它可能会打乱行动计划。首先,你必须决定“前5个”是什么意思。如果您只希望出现前5个,那么只需为in循环添加一个计数器变量,当它达到5时,使用break命令退出循环。