Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
768 views
in Technique[技术] by (71.8m points)

iphone - Obj-C: __block variables

Is it possible to assign a local variable a value whose scope is outside a block and have it retain its value? In particular, I'm coding for iOS and I have a nested block inside another blocks, and i want to assign a NSString a value inside the block a value and later (outside the blocks) use it. I tried using __block nut when i refer to the NSString after the blocks i get a bad access error. I am using ARC is that matters. For example:

__block NSString *str;

someBlock ^(id param1)
{
    str = @"iPhone";
}

[str getCharAtIndex:1]; //or w/e

Am i doin something conceptually wrong or this not allowed or what? Help is much appreciated.

Edit:

here's the actual code, basically the code gets the the tweet as a json object then all I'm tring to do is display the text. in the code i haven't extracted the text from the json, i was trying to do a proof of concept

- (IBAction)getTweet:(id)sender
{
    __block NSString *displayStr;

    //account instance
    ACAccountStore *store = [[ACAccountStore alloc] init];
    ACAccountType *twitterAcountType = 
                [store accountTypeWithAccountTypeIdentifier: ACAccountTypeIdentifierTwitter];

    //request access
    [store requestAccessToAccountsWithType: twitterAcountType withCompletionHandler:
     ^(BOOL granted, NSError *error)
     {
         if (!granted) {
             //display error on textView
         }
         else
         {
             //get available accounts
             NSArray *twitterAccounts = [store accountsWithAccountType: twitterAcountType];

             if([twitterAccounts count] > 0)
             {
                 //get first account
                 ACAccount *account = [twitterAccounts objectAtIndex: 0];

                 ////make authenticated request to twitter
                 //set-up params
                 NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
                 [params setObject:@"1"  forKey:@"include_entities"];
                 [params setObject:@"1" forKey:@"count"];

                 //which REST thing to call
                 NSURL *url = 
                 [NSURL URLWithString:@"http://api.twitter.com/1/statuses/home_timeline.json"];

                 //create request
                 TWRequest *request =
                 [[TWRequest alloc]
                        initWithURL:url parameters:params requestMethod:TWRequestMethodGET];

                 //attach account info
                 [request setAccount: account];
                 [request performRequestWithHandler:
                  ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
                  {
                     if(error != nil)
                     {
                         //display error
                     }
                     else
                     {
                         NSError *jsonError;
                         NSArray *timeline = 
                            [NSJSONSerialization 
                                    JSONObjectWithData: responseData
                                    options: NSJSONReadingMutableLeaves
                                    error: &jsonError];

                         if (jsonError == nil)
                         {
                             ///////////////////////////
                             ///heres the src of error//
                             ///////////////////////////
                             //display data
                             NSLog(@"array: %@", timeline);
                             displayStr = @"whats the deal with this";

      //i tried this but i think ARC takes care of this
                             [displayStr retain]; 
                         }
                         else
                         {
                             //display error
                         }
                     }

                  }];//end block de request
             }
             else
             {
                 //display error 
             }
         }
     }];//end block de store

    ///////then heres where i get the bad access error
    [self.lastTweetText setText:displayStr];


}//end getTweet

also thanks for the help guys

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're just defining that block, but not executing it. call someBlock(valueForParam1); to execute your block. Otherwise your str pointer points to some garbage and calling getCharAtIndex: crashes your app.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...