5

मुझे कस्टम एनएसओब्जेक्ट क्लास से ट्विटर टाइम लाइन डेटा मिल रहा है और इस वर्ग में एपीआई को कॉल करने और डेटा को पार्स करने के लिए सभी कोय हैं। मैं इस क्लास को अपने व्यू कंट्रोलर से कॉल कर रहा हूं जिसमें टेबल व्यू है और ट्विटर से आने वाले डेटा के साथ टेबलव्यू को पॉप्युलेट करने की आवश्यकता है। लेकिन dispatch_sync के साथ कुछ मुद्दों के कारण मेरा व्यू कंट्रोलर ट्विटर क्लास को कॉल करता है और नियंत्रण ऐरे से पहले व्यू कंट्रोलर पर वापस आता है (जिसे मैं टेबलव्यू पॉप्युलेट करने के लिए उपयोग कर रहा हूं) डेटा के साथ पॉप्युलेट किया जाता है।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

मेरा मतलब है एनएसएआरएआरए * temp = dataToDisplay; twitterDataLoad कक्षा में पूरे कोड को चलाने से पहले इस पंक्ति को बुलाया जाता है। – Ashutosh

+0

यह अजीब है। क्या आप 'tmpView.dataToDisplay = पूर्ण पर ब्रेकपॉइंट सेट कर सकते हैं; और देखें कि वास्तव में इसका कोई मूल्य है या नहीं? यदि ऐसा होता है, तो आपको '[डेटा लोडडाटा]' पर ब्रेकपॉइंट सेट करने की आवश्यकता है और यह देखने के लिए चरणबद्ध करें कि आपका 'एनएसएआरएआरए * temp = dataToDisplay'' [डेटा लोडडाटा] 'से पहले कैसे कॉल किया जाता है। – 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

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^