gpt4 book ai didi

ios - 如何从 block 内部修改非局部(全局)变量?

转载 作者:行者123 更新时间:2023-11-28 18:58:25 24 4
gpt4 key购买 nike

我是 Objective-C 的新手,必须动态更改

的值 <code>@property (strong, nonatomic) NSMutableArray *allCategories</code>

来自AFHTTPRequestOperationManager内部在 success阻止。
[self.allCategories addObject:tempObject];
不改变allCategories的值在循环中迭代。

变量已初始化为
self.allCategories = [[NSMutableArray alloc]init];
在 vi​​ewDidLoad 中。

我也试过创建一个临时变量 <code>__block NSMutableArray *tempCategories = [[NSMutableArray alloc]init];</code>在开始之前AFHTTPRequestOperationManager目的。 tempCategories甚至不保留它的值(value)。

无法弄清楚发生了什么。

编辑
抱歉给您带来的不便
viewDidLoad 有以下代码< br/> self.allCategories = [[NSMutableArray alloc]init];
[self loadData];

这是代码

-(NSMutableArray *)loadData
{
__block NSMutableArray *tempCategories = [[NSMutableArray alloc]init];

manager = [AFHTTPRequestOperationManager manager];

[manager GET:kAPICategoryList
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {

// downcast id to NSMutableDictionary
NSMutableDictionary *json = (NSMutableDictionary *)responseObject;

// check if dictionary is non nil has at least 1 element
if (json != nil && [json count] >= 1) {

// NSLog(@"json:\t%@", json);

// check json is non nil & has success message
if ([json objectForKey:kAPIKeyCategoryRoot] != nil) {

NSArray *arrCategoriesRoot = [json objectForKey:kAPIKeyCategoryRoot];

// check categories has some data
if (arrCategoriesRoot.count >= 1) {

for (int i = 0; i < arrCategoriesRoot.count; i++) {

SomeModel *pCategory;

NSDictionary *dctCategorySingle = [arrCategoriesRoot objectAtIndex:i];

// check category has sub category
if ([dctCategorySingle objectForKey:kAPIKeyCategorySubCategory] != nil) {
// create category with sub category
pCategory = [[SomeModel alloc]initWithSubCategorisedCategoryID:[dctCategorySingle objectForKey:kAPIKeyCategoryID]
name:[dctCategorySingle objectForKey:kAPIKeyCategoryName]
image:kIMGCategoryDefault
subCategory:[dctCategorySingle objectForKey:kAPIKeyCategorySubCategory]];
} else{
// create just a category
pCategory = [[SomeModel alloc]initWithCategoryID:[dctCategorySingle objectForKey:kAPIKeyCategoryID]
name:[dctCategorySingle objectForKey:kAPIKeyCategoryName]
image:kIMGCategoryDefault];
} // else just
[tempCategories addObject:pCategory];
[_allCategories addObject:pCategory];
} // for
NSLog(@"categories count %lu", [self.allCategories count]);
} // if count >= 1
}
else if ([json objectForKey:kAPIRespMsgCategoryFetchErrKey] != nil) {
[Utility showAlertWithTitle:kAPIRespMsgCategoryFetchErrKey
message:[json objectForKey:kAPIRespMsgCategoryFetchErrVal]
button:kMsgButtonOkayTtl];
}
} else {
// error in login => enable login
NSLog(@"%@", kMsgNetworkEmptyJSON);
}
}
// network error
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error %@", [error localizedDescription]);
}];
NSLog(@"tempCategories count %lu", [tempCategories count]);
return tempCategories;
}

这是 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

loadData 时finishes allCategories 中没有数据(无)。

最佳答案

据我所知,它应该以这种方式工作。您确定在检查 allCategories 的内容之前调用了成功 block 吗?

success block 异步工作,这意味着它只会在 RequestOperation 完成时执行(如果您正在下载大文件,这可能需要很长时间)

如果您试图在执行成功 block 之前获取allCategories 的值,您将无法获得预期的结果。我建议在您的成功 block 上使用断点或 NSLog 来查看它是否在您认为它正在执行时执行。

例如

 ...
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一 。您还应该阅读一些异步任务的工作原理。

基本上,您想要对异步操作/任务执行的操作是确保该值在您想要使用时可用。这样做的主要问题是您不知道何时该值将被设置,但您可以确定什么您想要在设置时执行什么。

为此,您可以创建一个带有自定义完成 block 的简单方法

- (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
}];

关于ios - 如何从 block 内部修改非局部(全局)变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29143998/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com