如何从块内部修改非本地(全局)变量?

时间:2015-03-19 11:58:57

标签: ios objective-c objective-c-blocks afnetworking-2

我对Objective-C& amp;必须从@property (strong, nonatomic) NSMutableArray *allCategories块中的@property (strong, nonatomic) NSMutableArray *allCategories内部动态更改

AFHTTPRequestOperationManager

的值。
success在迭代循环时,[self.allCategories addObject:tempObject];的值不会改变。{
变量已在viewDidLoad中初始化为
allCategories

我还尝试在启动self.allCategories = [[NSMutableArray alloc]init];对象之前创建一个临时变量__block NSMutableArray *tempCategories = [[NSMutableArray alloc]init];__block NSMutableArray *tempCategories = [[NSMutableArray alloc]init];甚至不保留其价值。

无法弄清楚发生了什么。

编辑
很抱歉给您带来不便,来自viewDidLoad的代码如下:AFHTTPRequestOperationManager
tempCategories

这里有代码

self.allCategories = [[NSMutableArray alloc]init];

这里是NSLog的输出形式:

2015-03-19 18:27:17.845 MyProject [4011:121268] viewDidLoad
2015-03-19 18:27:18.133 MyProject [4011:121268] tempCategories计数0
2015-03-19 18:27:18.136 MyProject [4011:121268] numberOfRowsInSection计数0
2015-03-19 18:27:18.137 MyProject [4011:121268] numberOfRowsInSection计数0
2015-03-19 18:27:19.019 MyProject [4011:121268]类别计数20

[self loadData];完成所有类别时没有数据(零)。

4 个答案:

答案 0 :(得分:4)

据我所知它应该这样工作..你确定在检查allCategories的内容之前是否调用了你的成功块吗?

成功阻止异步工作,这意味着只有在RequestOperation完成时才会执行(如果你下载的东西可能需要很长时间)

如果您尝试在之前获得allCategories 的值,则会执行成功阻止,但您无法获得您期望的内容。我建议您在成功模块中使用断点或NSLog,看看它是否在您认为执行时已被执行。

e.g

 ...
 successBlock:^(AFHTTPRequestOperation *operation, id responseObject)
 {
     NSLog(@"Success");
     [self.allCategories addObject:tempObject]
  }]; //End of request

[operation start]; //Begin executing the AFHTTPOperation

NSLog("%@",self.allCategories.description); //probably nil or empty
//since the success block hasn't been called yet  

编辑:

虽然我在异步操作设置之前返回一个值,但是从异步操作中返回一个值我建议看看这个answerthis。您还应该阅读一些异步任务的工作原理。

基本上您要对异步操作/任务执行的操作是确保在您想要使用它时可以使用该值。与此相关的主要问题是,您不知道何时设置了值,但您可以确保 您想要做什么。 s set。

为此,您可以使用自定义完成块

创建一个简单方法
- (void)myCustomMethodWithCompletionBlock: (void (^)(NSArray *))completion {
   //Do your request
   //...
   successBlock:^(AFHTTPRequestOperation *operation, id responseObject)
  {
      NSLog(@"Success");
      completionBlock(allCategories);
   }]; //End of request
}

同时在你的主要方法中你打电话

 [self myCustomMethodWithCompletionBlock:^(NSArray *allCategories) {
    self.allCategories = allCategories;
    //Do other stuff you need to with that variable since now you are
    //sure the value will be set unless the operation failed
   }];

答案 1 :(得分:0)

试试这个:

dispatch_async(dispatch_get_main_queue(), ^{
 [self.allCategories addObject:tempObject]; 
});

答案 2 :(得分:0)

前几天我遇到了同样的问题。我的问题是我的数组似乎为零,viewdidload方法中的数组分配可能是您在viewDidLoad之前运行的请求。如果您看到数组是nill然后将数组分配给不同的地方,请使用debug检查它。 P.S:我不是专家,但可能与我的问题相同。

答案 3 :(得分:0)

使用以下行定义NSMutableArray

@property (nonatomic, strong) NSMutableArray * arrData;
initialize

中的

viewDidLoad

- (void)viewDidLoad {

    [super viewDidLoad];

    self.arrData = [NSMutableArray array];
}

使用任何UIButton action调用以下方法,以查看output OR working behavior

- (void) TestMethod {

    dispatch_queue_t queue = dispatch_queue_create("myQueue", 0);

    dispatch_async(queue, ^{
        AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL urlWithEncoding:@"https://www.google.co.in/?gws_rd=ssl"]];
        [httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];
        [httpClient setDefaultHeader:@"Accept" value:@"application/json"];
        [httpClient setParameterEncoding:AFJSONParameterEncoding];
        NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:@"" parameters:nil];
        [request setTimeoutInterval:180];
        [AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/html"]];
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);

        AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
                                             {
                                                 [self.arrData addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"test",@"t3da",@"adsf",@"afds", nil]];
                                                 dispatch_semaphore_signal(sema);
                                             } failure:^ (NSURLRequest *request, NSURLResponse *response, NSError *error, id json){

                                                 [self.arrData addObject:[NSDictionary dictionaryWithObjectsAndKeys:@"test",@"t3da",@"adsf",@"afds", nil]];
                                                 dispatch_semaphore_signal(sema);
                                             }];

        [operation start];

        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        DLog(@"arrData = %@",self.arrData);
    });
}