Iphone UIActionSheet和Twitter用户名选择
我正在尝试实现一种方法,让用户从他们在iPhone(iOS5及更高版本)上设置的Twitter帐户中进行选择。我可以让用户名出现在UIActionSheet中,但由于某些原因,在调用该方法后,UIActionSheet大约需要5秒钟才能出现 我想可能是因为检索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
- (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命令退出循环。