Tôi nhận được dữ liệu dòng thời gian twitter từ một lớp NSObject tùy chỉnh và lớp này có tất cả các coe để gọi API và phân tích cú pháp dữ liệu. Tôi đang gọi lớp này từ bộ điều khiển xem của tôi có chế độ xem bảng và cần điền vào bảng nhìn cùng với dữ liệu đến từ twitter. Nhưng do một số vấn đề với dispatch_sync trình điều khiển xem của tôi gọi lớp twitter và điều khiển quay trở lại bộ điều khiển xem trước khi mảng (mà tôi đang sử dụng để điền bảng) được điền dữ liệu.Cách sử dụng dispatch_sync chính xác?
Dưới đây là một số mã:
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#import "SpinnerController.h"
#import "proAlertView.h"
#import "SBJson.h"
#import <Accounts/Accounts.h>
#import <Twitter/Twitter.h>
@interface TwitterDataLoad : NSObject<UIAlertViewDelegate>
{
NSMutableData * receivedData;
NSArray * results;
NSArray * cellContent;
NSMutableArray * totalContent;
SpinnerController * spinner;
proAlertView * av;
NSString *json_string;
NSDictionary * jsonResults;
SBJsonParser * parser;
NSMutableArray * dataForTable;
}
@property(nonatomic, strong) ACAccount * account;
@property(nonatomic, strong) NSArray * accounts;
@property(nonatomic, strong) ACAccountStore * accountStore;
@property (nonatomic ,retain) SecondViewController * tbView;
- (void)loadData;
@end
#import "TwitterDataLoad.h"
@interface TwitterDataLoad()
@end
@implementation TwitterDataLoad
@synthesize tbView;
-(id) init {
self = [super init];
if (self) {
[self loadData];
}
return self;
}
- (void)loadData
{
dataForTable = [[NSMutableArray alloc]init];
//Twitter new code
if (_accounts == nil) {
if (_accountStore == nil) {
_accountStore = [[ACAccountStore alloc] init];
}
ACAccountType *accountTypeTwitter =
[_accountStore
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[_accountStore requestAccessToAccountsWithType:accountTypeTwitter
withCompletionHandler:^(BOOL granted, NSError *error) {
if(granted) {
dispatch_sync(dispatch_get_main_queue(), ^{
_accounts = [_accountStore
accountsWithAccountType:accountTypeTwitter];
[self sendRequest];
});
}
}];
}
}
-(void) sendRequest {
totalContent = [[NSMutableArray alloc]init];
_account = [_accounts objectAtIndex:0];
TWRequest *postRequest = [[TWRequest alloc]
initWithURL:
[NSURL URLWithString:@"https://api.twitter.com/1/statuses/user_timeline.json?screen_name=test&count=20"]
parameters:nil
requestMethod:TWRequestMethodGET];
av = [[proAlertView alloc]initWithTitle:nil message:@"Getting latest news..." delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
UIActivityIndicatorView * indicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
indicator.frame = CGRectMake(120, 55, 35, 35);
[av addSubview:indicator];
[indicator startAnimating];
[av setBackgroundColor:[UIColor clearColor] withStrokeColor:[UIColor blackColor]];
[av show];
[postRequest setAccount:_account];
[postRequest performRequestWithHandler:^(NSData *responseData,
NSHTTPURLResponse *urlResponse,
NSError *error) {
if ([urlResponse statusCode] == 200) {
NSError *jsonError = nil;
results = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError];
dispatch_sync(dispatch_get_main_queue(), ^{
[av dismissAlert];
[self parseJson];
});
}
else {
[self showMessage];
}
}];
}
-(void)showMessage {
av = [[proAlertView alloc]initWithTitle:@"Connection Problem" message:@"Please confirm the device is connected to the Internet." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[av setBackgroundColor:[UIColor clearColor] withStrokeColor:[UIColor blackColor]];
[av show];
}
-(void)parseJson {
NSMutableArray * complete = [[NSMutableArray alloc]init];
for (NSDictionary * tweets in results)
{
NSString * status = [tweets objectForKey:@"text"];
NSString * date = [tweets objectForKey:@"created_at"];
NSDictionary * user = [tweets objectForKey:@"user"];
NSString * artistName = [user objectForKey:@"name"];
NSString * screenName = [user objectForKey:@"screen_name"];
NSString * artistImage = [user objectForKey:@"profile_image_url"];
cellContent = [NSArray arrayWithObjects:status,date,artistName,screenName,artistImage, nil];
[complete addObject:cellContent];
}
SecondViewController * tmpView = [[SecondViewController alloc]initWithNibName:@"SecondViewController_iPhone" bundle:nil];
tmpView.dataToDisplay = complete;
}
lớp này đã được gọi là như thế này:
- (void)viewDidLoad
{
[super viewDidLoad];
TwitterDataLoad * data = [[TwitterDataLoad alloc] init];
[data loadData];
NSArray * temp = dataToDisplay;
}
Tôi biết tôi đang trở về giá trị trong một cách sai lầm, nhưng tôi đã cố gắng trở về nó thông qua thông điệp loadData chính nó cho bộ điều khiển xem nhưng nó không hoạt động hoặc vì vậy tôi đã chỉ cố gắng này. Xin đừng quan tâm về điều đó.
Cảm ơn
Ý của bạn là "điều khiển quay lại bộ điều khiển xem trước Array"? Kiểm soát là gì? – yeesterbunny
Tôi có nghĩa là NSArray * temp = dataToDisplay; dòng này được gọi trước khi toàn bộ mã được thực hiện chạy trong lớp twitterDataLoad. – Ashutosh
Điều đó thật kỳ lạ. Bạn có thể đặt breakpoint tại 'tmpView.dataToDisplay = complete;' và xem nó có thực sự có giá trị không? Nếu có, thì bạn cần đặt breakpoint tại '[data loadData]' và bước vào nó để xem cách 'NSArray * temp = dataToDisplay' của bạn được gọi trước' [data loadData] '. – yeesterbunny