【问题标题】:Declaring Variables in Blocks, Objective C在块中声明变量,Objective C
【发布时间】:2012-08-08 18:25:28
【问题描述】:

线程我的项目,但使用队列和块,但当我尝试将代码排队时出现错误。我知道你不能在块中排队 UI 元素,所以我避免了这种情况,但我得到的错误是当我在块外调用 UI 元素时,它说虽然变量在块内声明但未声明变量。这是代码。该代码是一个 UITableView 方法,它只需要一个数组对其进行排序并显示它。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Create an instance of the cell
UITableViewCell *cell;
cell = [self.tableView dequeueReusableCellWithIdentifier:@"Photo Description"];

if(!cell)
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Photo Description"];

// set properties on the cell to prepare if for displaying
//top places returns an array of NSDictionairy objects, must get object at index and then object for key

//Lets queue this
dispatch_queue_t downloadQueue = dispatch_queue_create("FlickerPhotoQueue", NULL);
dispatch_async(downloadQueue, ^{

//lets sort the array

NSArray* unsortedArray = [[NSArray alloc] initWithArray:[[self.brain class] topPlaces]] ;
//This will sort the array
NSSortDescriptor* descriptor = [NSSortDescriptor sortDescriptorWithKey:@"_content" ascending:YES];
NSArray * sortDescriptors = [NSArray arrayWithObject:descriptor];                                   
NSArray *sortedArray = [[NSArray alloc] init];
sortedArray = [unsortedArray sortedArrayUsingDescriptors:sortDescriptors];

NSString * cellTitle = [[sortedArray objectAtIndex:self.location] objectForKey:@"_content"]; 

NSRange cellRange = [cellTitle rangeOfString:@","];

NSString * cellMainTitle = [cellTitle substringToIndex:cellRange.location];

});
dispatch_release(downloadQueue);  

//Claims that this are not declared since they are declared in the block
cell.textLabel.text = cellMainTitle;
//This isnt declared either
NSString* cellSubtitle = [cellTitle substringFromIndex:cellRange.location +2];

cell.detailTextLabel.text =  cellSubtitle;
self.location++;
return cell;
}

我设法通过将调度发布移动到代码块的最后,然后通过调用 dispatch_get_main_queue 在主线程中声明 UI 接口来让程序工作。感谢大家的帮助

【问题讨论】:

  • 请注意,我对此并不完全确定,但我认为您遇到了范围问题。每当您在 {} 之间放置任何内容时,在其中声明的所有变量都会在其结束时过期。此外,我相信块的工作原理很像函数。长话短说,尝试在块外声明 cellMainTitle,将其设置在块内,然后再使用它。这可能会解决您的问题(并可能导致另一个问题,称为并发)
  • 并发就是你在做的事情:通过线程同时运行多条代码路径,可以手动处理线程,也可以使用 GCD。
  • 是的,您不能这样做,但更重要的是,为什么要在 cellForRowAtIndexPath 中对数组进行排序 - 在填充表格之前创建并排序数组 - 此方法仅用于获取一个单元格的内容。并摆脱 GCD 块,在这种情况下它可能会使您的 UI 变得更慢。
  • 是的,我知道我的 UI 很慢,因为这个原因
  • 你的意思是你不能那样做?

标签: objective-c xcode variables queue block


【解决方案1】:

如果我正确理解了您的问题,那么您是在块内声明一个变量并尝试在外部使用它。

那行不通。在块内声明的变量仅限于块的范围。如果您在块内创建它们,则只能在块中使用它们,并且不能在其他任何地方使用它们。

一个更好的主意是创建要在块外使用的变量。如果要修改块中的变量,请使用 __block 关键字。

__block UITableViewCell *someCell;
//__block tells the variable that it can be modified inside blocks.
//Some generic block
^{
//initialize the cell here.
}

【讨论】:

  • 你会建议我如何声明这些变量然后在一个块中使用?
  • 我刚刚编辑了答案以添加这些详细信息。它现在的语法有点懒惰(我现在正在上大学),但它告诉你你需要修改的 __block。
  • 当然,这可能会导致其他问题,因为cellMainTitle 等在使用时可能无法正确设置它们的值(在cell.textLabel.text = cellMainTitle; 等中) )。
  • 是的,这是需要注意的。也许最好的想法是将所有数据加载到其他地方,而不是尝试使用 cellForRowAtIndexPath 动态加载它。虽然不确定 Terrel Gibson 想要做什么,所以我无法提供任何替代方案。
【解决方案2】:

在块内定义的变量是该块的本地变量,因此不存在于该块之外。您可以在进入块之前预先定义这些变量,但是这是进入一个专门的领域,并且在定义这些变量时需要使用扩展。在 Organizer 中查找“__block”存储类型。考虑到细节,我没有花太多时间查看您的代码,以了解这是否是明智的建议。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    相关资源
    最近更新 更多