Obj-C:__block 变量 [英] Obj-C: __block variables

查看:18
本文介绍了Obj-C:__block 变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以为局部变量分配一个范围在块之外的值并让它保留其值?特别是,我正在为 iOS 编码,并且我在另一个块内有一个嵌套块,我想在块内为 NSString 分配一个值,然后(在块外)使用它.当我在块后引用 NSString 时,我尝试使用 __block nut,我得到一个错误的访问错误.我正在使用 ARC,这很重要.例如:

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.

这是实际代码,基本上代码将推文作为 json 对象获取,然后我要做的就是显示文本.在我没有从 json 中提取文本的代码中,我试图做一个概念证明

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

也感谢大家的帮助

推荐答案

首先,str只有在block执行后才会更新.因此,除非您对该块使用 dispatch_sync 否则在这一行:[str getCharAtIndex:1]; 该块不太可能被执行并且 str 不会更新.

First, str will get updated only after the block is executed. So unless you are using dispatch_sync for that block otherwise at this line:[str getCharAtIndex:1]; the block is unlikely to be executed and str will not get updated.

其次,如果你不使用 ARC,__block 变量不会被块对象自动保留.这意味着,如果您不保留它,那么当您访问 str 时,str 可能是一个已释放的对象并导致您的应用程序崩溃.

Second, __block variable will not automatic retained by the block object if you are not using ARC. This means if you are not retain it, than by the time you accessing str, str may be a deallocated object and crash your app.

这篇关于Obj-C:__block 变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆