5

커스텀 NSObject 클래스의 트위터 타임 라인 데이터를 얻고 있는데이 클래스는 API를 호출하고 데이터를 파싱하기위한 모든 coe를가집니다. 테이블 뷰가 있고 내 트위터에서 오는 데이터로 테이블 뷰를 채워야하는 뷰 컨트롤러에서이 클래스를 호출합니다. 그러나 dispatch_sync와 관련된 일부 문제로 인해 내 View Controller는 twitter 클래스를 호출하고 배열 (Tableview를 채우는 데 사용하는)이 데이터로 채워지기 전에 컨트롤이 View Controller로 돌아옵니다.dispatch_sync를 올바르게 사용하는 방법은 무엇입니까?

#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; 
} 

이 클래스는 다음과 같이 호출 된 : 여기

는 일부 코드의 내가 잘못된 방법으로 값을 반환하고 알고

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    TwitterDataLoad * data = [[TwitterDataLoad alloc] init]; 
    [data loadData]; 
    NSArray * temp = dataToDisplay; 
} 

하지만 난 loadData 메시지를 통해 복귀 시도 그 자체가 뷰 컨트롤러에 있지만 그 중 하나를 작동하지 않았다 그래서 그냥이 시도했다. 제발 신경 쓰지 마세요.

감사

+0

"컨트롤이 배열 이전의보기 컨트롤러로 돌아옵니다"라는게 무슨 뜻입니까? 컨트롤이란 무엇입니까? – yeesterbunny

+0

NSArray * temp = dataToDisplay;를 의미합니다. 이 코드는 twitterDataLoad 클래스에서 전체 코드가 실행되기 전에 호출됩니다. – Ashutosh

+0

이상합니다. 'tmpView.dataToDisplay = complete;'에서 중단 점을 설정하고 실제로 값이 있는지 확인할 수 있습니까? 그렇다면'[data loadData]'에 중단 점을 설정하고'NSArray * temp = dataToDisplay'가'[data loadData]'전에 어떻게 호출되는지 살펴보아야합니다. – yeesterbunny

답변

2

내가이 문제를 알아 냈습니다. dispatch_sync가이 문제를 어떻게해야되는 일을되어 dispatch_sync가 불려되고있는 다른 두 문 (다른 블록)

[_accountStore requestAccessToAccountsWithType:accountTypeTwitter 
             withCompletionHandler:^(BOOL granted, NSError *error) 

그래서 이것은 비동기 호출이며, 파견 동기화가 때 프로그램 호출되는 함께 제어가 메인 큐에 돌아 오면 다음과 같이 정의됩니다. dispatch_sync (dispatch_get_main_queue()) 컨트롤이 메인 대기열에 돌아 가기 전에 메서드가 반환되므로 배열에 아무런 값도 표시되지 않습니다. 그래서이 문제를 해결하기 위해이 데이터 호출이 끝나면 반환 호출을받는 호출 클래스에 블록을 작성했습니다. 전체 코드를 원한다면 이메일을 보내주세요. @ ghostsmitm @ gmail.com

0

당신은 당신의 UITableView 데이터가로드 된 후에 reloadData를 호출해야합니다. loadData을 호출 한 후에이 작업을 수행 할 수 있습니다.

+0

그 후 나는 그것을하고있다. 그러나 그것은 전체 트위터의 일 전에 부름을 받는다. – Ashutosh

관련 문제