Предупреждение анализатора в Facebook API для iOS

Вот код из файла APICallsViewController и несколько скриншотов. мое приложение падает, и я не уверен, является ли это причиной.

спасибо за любую помощь

 // Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UILabel *textLabel;
    UILabel *detailTextLabel;
    UIButton *button;

    UIFont *cellFont = [UIFont boldSystemFontOfSize:14.0];
    UIFont *detailCellFont = [UIFont fontWithName:@"Helvetica" size:12.0];

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        // Initialize API title UILabel
        textLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
        textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
        textLabel.tag = TITLE_TAG;
        textLabel.font = cellFont;
        [cell.contentView addSubview:textLabel];

        // Initialize API description UILabel
        detailTextLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
        detailTextLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
        detailTextLabel.tag = DESCRIPTION_TAG;
        detailTextLabel.font = detailCellFont;
        detailTextLabel.textColor = [UIColor darkGrayColor];
        detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
        detailTextLabel.numberOfLines = 0;
        [cell.contentView addSubview:detailTextLabel];

        // Initialize API button UIButton
        button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        button.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
        [button setBackgroundImage:[[UIImage imageNamed:@"MenuButton.png"]
                                    stretchableImageWithLeftCapWidth:9 topCapHeight:9]
                          forState:UIControlStateNormal];
        [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(apiButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
        [cell.contentView addSubview:button];
    } else {
        textLabel = (UILabel *)[cell.contentView viewWithTag:TITLE_TAG];
        detailTextLabel = (UILabel *)[cell.contentView viewWithTag:DESCRIPTION_TAG];
        // For the button cannot search by tag since it is not constant
        // and is dynamically used figure out which button is clicked.
        // So instead we loop through subviews of the cell to find the button.
        for (UIView *subview in cell.contentView.subviews) {
            if([subview isKindOfClass:[UIButton class]]) {
                button = (UIButton *)subview;
            }
        }
    }

    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);

    // The API title
    NSString *cellText = [[apiMenuItems objectAtIndex:indexPath.row] objectForKey:@"title"];
    CGSize labelSize = [cellText sizeWithFont:cellFont
                            constrainedToSize:constraintSize
                                lineBreakMode:UILineBreakModeWordWrap];
    textLabel.frame = CGRectMake(20, 2,
                                  (cell.contentView.frame.size.width-40),
                                  labelSize.height);
    textLabel.text = cellText;

    // The API description
    NSString *detailCellText = [[apiMenuItems objectAtIndex:indexPath.row] objectForKey:@"description"];
    CGSize detailLabelSize = [detailCellText sizeWithFont:detailCellFont
                                        constrainedToSize:constraintSize
                                            lineBreakMode:UILineBreakModeWordWrap];
    detailTextLabel.frame = CGRectMake(20, (labelSize.height + 4),
                                       (cell.contentView.frame.size.width-40),
                                       detailLabelSize.height);
    detailTextLabel.text = detailCellText;


    // The API button
    CGFloat yButtonOffset = labelSize.height + detailLabelSize.height + 15;
    button.frame = CGRectMake(20, yButtonOffset, (cell.contentView.frame.size.width-40), 44);
    [button setTitle:[[apiMenuItems objectAtIndex:indexPath.row] objectForKey:@"button"]
            forState:UIControlStateNormal];
    // Set the tag that will later identify the button that is clicked.
    button.tag = indexPath.row;


    return cell;
}

2 ответа

Решение

В else заявление UIButton *button не инициализируется. Посмотрите, как в операторе if это:

button = [UIButton buttonWithType:UIButtonTypeRoundedRect];

но в else инициализация отсутствует. Вы можете поставить после:

} else {
        textLabel = (UILabel *)[cell.contentView viewWithTag:TITLE_TAG];
        detailTextLabel = (UILabel *)[cell.contentView viewWithTag:DESCRIPTION_TAG];
        button = (UIButton *)[cell.contentView viewWithTag:indexPath.row]; // <---- add this

И переместить это:

button.tag = indexPath.row;

до

[cell.contentView addSubview:button];

в конце оператора if...

button Переменная является локальной переменной. Если вы не используете ARC, не гарантируется, что он будет инициализирован ни к чему. Это может быть чепуха. Анализатор предупреждает вас, что не ясно, что ему был присвоен значимый адрес к тому времени, когда вы пытаетесь отправить ему сообщение (установщик для frame свойство - это сообщение, которое вы отправляете).

Учти это: cell не является nil, и вы не найдете кнопку в его подпредставлениях. Если это так, то приложение достигнет рассматриваемой линии, даже не назначив button переменная. Он может содержать указатель на абсолютно любое место. Если вы попытаетесь разыменовать указатель, чтобы отправить сообщение объекту, вы можете чертить память в любом месте вашего приложения.

Теперь, возможно, вы знаете, что гарантированно найдется подкласс, который является кнопкой. Но анализатор не может понять это. Так что это предупреждает вас независимо.

Вы должны инициализировать button переменная к nil, Если есть возможность не найти кнопку, вам следует заняться этим делом.

Другие вопросы по тегам