Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/44.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 为什么这条线用水管冲洗我的桌面cell=[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];_Iphone_Uitableview_Delegates - Fatal编程技术网

Iphone 为什么这条线用水管冲洗我的桌面cell=[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

Iphone 为什么这条线用水管冲洗我的桌面cell=[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];,iphone,uitableview,delegates,Iphone,Uitableview,Delegates,当我在cellForRowAtIndexPath:函数中注释掉这一行时: cell = (tvcCustomCellWithSetter *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier]; …然后所有的细胞每次都会再生,而不是重复使用。。。这会使我的所有tableview单元格当前值都得到完美设置。但是,我的单元格需要显示新旧值。当然,因为单元格总是被分配的,所以所有的历史值都会丢失 …当我将该行保留在那里

当我在cellForRowAtIndexPath:函数中注释掉这一行时:

cell = (tvcCustomCellWithSetter *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
…然后所有的细胞每次都会再生,而不是重复使用。。。这会使我的所有tableview单元格当前值都得到完美设置。但是,我的单元格需要显示新旧值。当然,因为单元格总是被分配的,所以所有的历史值都会丢失

…当我将该行保留在那里并滚动到tableview的底部时,表格底部单元格中的值将包含属于顶部单元格的一些值。。。我有点搞混了

简而言之,我有一个由自定义UITableViewCells组成的UITableView。自定义单元格具有以下功能:

Uisteper控件 用于存储调用的tableView的id委托,以便我可以在tableView中运行方法。 允许每个单元格在tableview中存储其节和行的属性 问题陈述: 当我加载tableview,用户点击单元格中的UIStepper控件时,它会调用委托函数doit:,返回tableview实现。在该函数中,自定义单元格的section和row属性工作正常,它们完美地指向数据源和tableView中的正确section和row,但是stepper.value以某种方式被设置为表中另一个单元格的stepper.value

而且,我只在表格中滚动显著距离时才真正注意到这种异常情况……例如。自上而下。底部单元格的stepper.value将是表格顶部附近单元格的stepper.value。所以我想我遇到了一个复杂的问题,源于细胞的缓存方式,等等

我包含了customCell类以及父表视图中的代码

有人看到我的错误吗?非常感谢

这是customTableViewCell头文件

回到实际的TableView,在那里我实例化了自定义单元格,我调用了自定义单元格的setDelegate:方法,如下所示,以便能够理解表中的哪个单元格被单击

该节目的主角是UIStepper控件,它允许用户上下移动屏幕 得分值,该值也显示在单元格上

#import <UIKit/UIKit.h>

@interface tvcCustomCellWithSetter : UITableViewCell {
    id delegate;
    NSNumber * row;
    NSNumber * section;
    int      originalValueIsSet; }

@property (nonatomic, assign) IBOutlet UILabel *score; @property
(nonatomic, assign) IBOutlet UILabel *catAndWeight; @property
(nonatomic, assign) IBOutlet UILabel *orgValueText; @property
(nonatomic, assign) IBOutlet UILabel *orgValueValue; @property
(nonatomic, assign) IBOutlet UIStepper *theStepper; @property
(nonatomic, assign) id delegate; @property (nonatomic, assign)
NSNumber *row; @property (nonatomic, assign) NSNumber *section;
@property (nonatomic, assign) int originalValueIsSet;

- (IBAction) bumpTheScore;
- (id)delegate;
- (void)setDelegate:(id)newDelegate;

@end
这是包含customViewCell对象的TableView

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    tvcCustomCellWithSetter *cell = nil;

    cell = (tvcCustomCellWithSetter *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];
        for(id currentObject in topLevelObjects){
            if([currentObject isKindOfClass:[tvcCustomCellWithSetter class]]) {
                cell = (tvcCustomCellWithSetter *)currentObject;
                break;
            }
        }


    } 

    // since the cell is a custom cell and it lives in a new class file, when events 
    // occur from toys in that cell (i.e. sliders, stepper, etc), the events go to that
    // class file.  I want those events to go to the simgrades class and run a reactive
    // function in there.  this is how you do that.   see the two functions in the 
    // custom class that work with this line.
    [cell setDelegate:self];

    // similarly, save the current section and row into the custom cell itself
    // so that later, when the stepper is clicked on one of the cells, we'll be able
    // to know the location in the datasource that is being addressed by the user.
    [cell setRow: [NSNumber numberWithInt: indexPath.row]];
    [cell setSection: [NSNumber numberWithInt: indexPath.section]];      

    // Set up the cell...
    [self.tableView setAllowsSelectionDuringEditing:NO];
    SimCat *tmpCat = [simCatalog objectAtIndex: indexPath.section];
    SimGrade *tmpGrd = [[tmpCat simGrades] objectAtIndex:indexPath.row];

    float averageScore, _score, _total;
    _score = [tmpGrd.scoreValue floatValue];
    _total = [tmpGrd.scorePossible floatValue];
    averageScore = (_score / _total) * 100;

    // Configure the cell...  Category name and description
    if (tmpGrd.isSimGrade) {
        cell.score.text = [NSString stringWithFormat:@"SimGrade: %2.2f%% - (%@ of %@)", averageScore, [tmpGrd.scoreValue stringValue] , [tmpGrd.scorePossible stringValue]];
        //for simulation grades, null out the orgValue labels.
        cell.orgValueValue.text = [NSString stringWithString: @""];
        cell.orgValueText.text = [NSString stringWithString: @""];
    } else {
        cell.score.text = [NSString stringWithFormat:@"Actual: %2.2f%% - (%@ of %@)", averageScore, [tmpGrd.scoreValue stringValue] , [tmpGrd.scorePossible stringValue]];
        //set the orig value label and turn on the boolean that shows that you've set this already.
        if (! cell.originalValueIsSet ) {
            cell.orgValueValue.text = [NSString stringWithFormat:@"%@", [tmpGrd.scoreValue stringValue]];
            cell.orgValueText.text = [NSString stringWithString: @"Original Value:"];
            cell.originalValueIsSet = true;
        }
    }

    cell.catAndWeight.text = [NSString stringWithFormat:@"Category: %@, Wt: %d", tmpCat.catName, [[tmpCat catWeight] intValue]];

    [cell.theStepper setValue:[tmpGrd.scoreValue floatValue]];
    [cell.theStepper setMaximumValue:[tmpGrd.scorePossible floatValue]];
    [cell.theStepper setMinimumValue:0];

    return cell;
}
这就是我的问题所在。请参阅下面代码中的问题描述

- (void) doit: (id) sender {

    NSLog(@"it worked - i got back inside the tableview that houses the custom cells");
    NSLog(@"the user touched the UISetter control on a cell in section: %d", [[(tvcCustomCellWithSetter *)sender section] intValue]);
    NSLog(@"and that cell was in row: %d of that section", [[(tvcCustomCellWithSetter *)sender row] intValue]);

    // find the right section and row in the tableview's data source
    // point to the section indicated by the "section" passed in from the custom cell.
    SimCat *cat = [simCatalog objectAtIndex:[[(tvcCustomCellWithSetter *)sender section] intValue] ];

    // now point at the array item that corresponds to the "row" passed in from the custom cell
    SimGrade *grade = [[cat simGrades] objectAtIndex:[[(tvcCustomCellWithSetter *)sender row] intValue]];

    // now that we are pointing at the right array item in the tableview's datasource, update it's value to that of the UIStepper
    // control's value.
    // THE PROBLEM OCCURS IN THE FOLLOWING LINES.  The before value that is printed out is perfect.  So I know I am able to 
    // reference the correct value in the datasource that the user has just incremented or decremented with the UIStepper
    // control.  The "theStepper.value" should contain a number that is one more or one less than the previous value...
    // HOWEVER, the value stored in theStepper.value is actually a value from one of the other cells in the table.
    // I'm thinking that this has to do with the way the table cells are cached.  I usually see this error when I scroll to the
    // bottom of the tableview.  

    NSLog(@"before: %f", [[grade scoreValue] floatValue]);
    grade.scoreValue = [NSNumber numberWithFloat: [[(tvcCustomCellWithSetter *)sender theStepper] value]];
    NSLog(@"after: %f", [[grade scoreValue] floatValue]);

    // you have changed some values in the Tableview's datasource so you should repaint the view.
    [self loadHTMLHeader];
    [[self tableView] reloadData];

    return;
}
为了防止步进值传递,如果您的dequeueReusableCell。。方法返回一个单元格

因此:

一旦您这样做了,您就可以进行进一步的调试,看看您的值是否设置得不正确。如果值为零,那么它应该是零。否则,您就知道它无法为特定的单元格设置正确的值,然后在代码中放置断点并查看变量值等

编辑:我会更具体一些。从调试中,您将在逐步完成代码时看到:

在设置正确的值之前,将步进器值显式设置为默认值,或 这些值没有显式设置为默认值,这意味着您的值重置代码不起作用。 然后:

步进器值设置为当前单元格的正确值,或 步进器值设置为与预期值不同的值,在这种情况下,您需要在设置该值的点跟踪代码,并查看索引是什么以及它最终拾取的值,等等,或者 步进器值与其默认值完全没有改变,这意味着要设置的代码正在崩溃,或者出现了一种不寻常的情况,即您最终得到一个nil、0或根本没有执行代码来设置值,您需要跟踪并查看代码到达该阶段的位置。
这应该是您的标准调试过程。

我最终解决了这一问题,方法是将我的头撞到墙上,并对UIStepper类进行子类化,以便添加一个row和section属性,使我能够确定单击控件时显示控件的是哪个tableview单元格。我还使用了一个setTarget方法,在cellforrowatindexpath方法期间放置在每个单元格上,每当UIStepper上的值发生更改时,它都会调用tableview类中的函数。在这个函数中,我能够利用customStepper中的行和节值来精确定位表中的行,从而确定需要更新的数据源


唷。

您将所有属性标记为assign-@property非原子,assign ibuiLabel*score;。更正确的方法是将其标记为保留。谢谢,铍。但我把所有的都改成了“保留”,没有快乐。下面是问题陈述的更新。当我在TableView中注释掉下面的行时,单元格不会被重用,UIStepper.value是正确的。但这破坏了我保持细胞原始分数值的能力,因为每个细胞每次都会再生。我
在单元格中显示新旧值。这是我上面提到的行:cell=tvcCustomCellWithSetter*[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];谢谢,darvidsOn,我会设置它并尝试一些断点调试。回到你身边:20米。不,没有欢乐。我真的被这件事难住了。还有其他建议吗?
- (void) doit: (id) sender {

    NSLog(@"it worked - i got back inside the tableview that houses the custom cells");
    NSLog(@"the user touched the UISetter control on a cell in section: %d", [[(tvcCustomCellWithSetter *)sender section] intValue]);
    NSLog(@"and that cell was in row: %d of that section", [[(tvcCustomCellWithSetter *)sender row] intValue]);

    // find the right section and row in the tableview's data source
    // point to the section indicated by the "section" passed in from the custom cell.
    SimCat *cat = [simCatalog objectAtIndex:[[(tvcCustomCellWithSetter *)sender section] intValue] ];

    // now point at the array item that corresponds to the "row" passed in from the custom cell
    SimGrade *grade = [[cat simGrades] objectAtIndex:[[(tvcCustomCellWithSetter *)sender row] intValue]];

    // now that we are pointing at the right array item in the tableview's datasource, update it's value to that of the UIStepper
    // control's value.
    // THE PROBLEM OCCURS IN THE FOLLOWING LINES.  The before value that is printed out is perfect.  So I know I am able to 
    // reference the correct value in the datasource that the user has just incremented or decremented with the UIStepper
    // control.  The "theStepper.value" should contain a number that is one more or one less than the previous value...
    // HOWEVER, the value stored in theStepper.value is actually a value from one of the other cells in the table.
    // I'm thinking that this has to do with the way the table cells are cached.  I usually see this error when I scroll to the
    // bottom of the tableview.  

    NSLog(@"before: %f", [[grade scoreValue] floatValue]);
    grade.scoreValue = [NSNumber numberWithFloat: [[(tvcCustomCellWithSetter *)sender theStepper] value]];
    NSLog(@"after: %f", [[grade scoreValue] floatValue]);

    // you have changed some values in the Tableview's datasource so you should repaint the view.
    [self loadHTMLHeader];
    [[self tableView] reloadData];

    return;
}
cell = (tvcCustomCellWithSetter *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"customCell" owner:self options:nil];
    for(id currentObject in topLevelObjects){
        if([currentObject isKindOfClass:[tvcCustomCellWithSetter class]]) {
            cell = (tvcCustomCellWithSetter *)currentObject;
            break;
        }
    }
} else {
    cell.theStepper.value = 0;
    cell.theStepper.maximumValue = 1;
    // cell.theStepper.minimumValue = 0; this should already be set properly
}