Khi chuyển đổi một dự án để sử dụng ARC, trường hợp chuyển đổi trong phạm vi được bảo vệ là gì?


283

Khi chuyển đổi một dự án để sử dụng ARC, "trường hợp chuyển đổi nằm trong phạm vi được bảo vệ" nghĩa là gì? Tôi đang chuyển đổi dự án để sử dụng ARC, sử dụng Xcode 4 Chỉnh sửa -> Refactor -> Chuyển đổi sang Objective-C ARC ... Một trong những lỗi tôi nhận được là "trường hợp chuyển đổi nằm trong phạm vi được bảo vệ" trên "một số" các công tắc trong một trường hợp chuyển đổi.

Chỉnh sửa, đây là mã:

ERROR được đánh dấu trong trường hợp "mặc định":

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"";
    UITableViewCell *cell ;
    switch (tableView.tag) {
        case 1:
            CellIdentifier = @"CellAuthor";
            cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
            if (cell == nil) {
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        cell.textLabel.text = [[prefQueries objectAtIndex:[indexPath row]] valueForKey:@"queryString"];
        break;
    case 2:
        CellIdentifier = @"CellJournal";
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        cell.textLabel.text = [[prefJournals objectAtIndex:[indexPath row]] valueForKey:@"name"];

        NSData * icon = [[prefJournals objectAtIndex:[indexPath row]] valueForKey:@"icon"];
        if (!icon) {
            icon = UIImagePNGRepresentation([UIImage imageNamed:@"blank72"]);
        }
        cell.imageView.image = [UIImage imageWithData:icon];

        break;

    default:
        CellIdentifier = @"Cell";
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            }
        break;
    }


    return cell;
}

Câu trả lời:


651

Bao quanh mỗi trường hợp chính nó với niềng răng {}. Điều đó sẽ khắc phục vấn đề (nó đã làm cho tôi trong một trong các dự án của tôi).


12
Các dấu ngoặc giúp trình biên dịch hiểu phạm vi. Tôi biết GCC đã từng đưa ra cảnh báo nếu bạn khai báo một biến mới ở dòng đầu tiên của câu lệnh tình huống mà không có dấu ngoặc nhọn, và video WWDC 2011 trên ARC đề cập đến điều gì đó về việc bao quanh các trường hợp trong dấu ngoặc nhọn. Nếu bạn muốn biết lý do tại sao, hãy xem video mà tôi không thể nhớ ra khỏi đỉnh đầu.
FeifanZ

87
Đã được một thời gian, nhưng tôi dường như nhớ một cái gì đó trong tiêu chuẩn C không cho phép gán biến sau một câu lệnh tình huống vì mã không thực sự nằm trong một khối. Bằng cách thêm dấu ngoặc nhọn {...}sau casevà trước break, mọi thứ bên trong nằm trong một khối có phạm vi và sẽ hoạt động như mong đợi. Tôi đã nhận ra rằng tôi chỉ tự động đưa ra một casetuyên bố để tránh vấn đề này.
Paul

2
Tôi gặp vấn đề tương tự. Đó là một thông báo lỗi khủng khiếp và một lỗi đã được gửi (sẽ được sửa trong phiên bản tương lai của trình biên dịch) để sửa nó. Nhưng, vâng, các quy tắc phạm vi trong các báo cáo trường hợp trong C thực sự rất ... kỳ quặc.
bbum

59
Điều này xảy ra bởi vì bạn đang khai báo một biến mới trong phạm vi vụ án. Trình biên dịch không biết làm thế nào biến này nên được đặt trong phạm vi (nó thuộc về tất cả các trường hợp chuyển đổi hay chỉ là trường hợp hiện tại?) Bao bọc việc thực hiện của trường hợp trong ngoặc tạo ra một phạm vi cho biến nằm trong để trình biên dịch có thể quản lý đúng đó là cuộc sống.
Shinohara

1
Lưu ý rằng điều này cũng có thể xảy ra khi khai báo một biến trong một khối trong câu lệnh tình huống không có dấu ngoặc nhọn. Đó là một người gãi đầu trong một hoặc hai phút. =)
slycrel

14

Khó có thể chắc chắn nếu không nhìn vào mã, nhưng điều đó có thể có nghĩa là có một số khai báo biến đang diễn ra bên trong công tắc và trình biên dịch không thể biết liệu có đường dẫn rõ ràng đến điểm dealloc cần thiết hay không.


9

Có 2 cách dễ dàng để giải quyết vấn đề này:

  • Bạn có thể đang khai báo các biến. Di chuyển khai báo các biến bên ngoài câu lệnh switch
  • Đặt toàn bộ khối trường hợp vào giữa dấu ngoặc nhọn {}

Trình biên dịch không thể tính toán dòng mã khi các biến được phát hành. Gây ra lỗi này.


5

Đối với tôi, vấn đề bắt đầu ở giữa một công tắc và dấu ngoặc nhọn không hoạt động, trừ khi bạn phải bao gồm {} IN TẤT CẢ các báo cáo trường hợp trước đó. Đối với tôi, lỗi xảy ra khi tôi có tuyên bố

NSDate *start = [NSDate date];

trong trường hợp trước. Sau khi tôi xóa cái này, thì tất cả các báo cáo trường hợp tiếp theo sẽ sạch khỏi thông báo lỗi phạm vi được bảo vệ


Điều tương tự; trường hợp lỗi ở giữa. Tôi chỉ phải di chuyển khai báo biến trên công tắc (nó không phụ thuộc vào trường hợp). Tôi không phải thêm niềng răng xung quanh các trường hợp (lần này).
eGanges

3

Trước:

    case 2:
        NSDate *from = [NSDate dateWithTimeIntervalSince1970:1388552400];
        [self refreshContents:from toDate:[NSDate date]];
        break;

Tôi đã di chuyển định nghĩa NSDate trước khi chuyển đổi và nó đã khắc phục vấn đề biên dịch:

NSDate *from;  /* <----------- */
switch (index) {
    ....
    case 2:
        from = [NSDate dateWithTimeIntervalSince1970:1388552400];
        [self refreshContents:from toDate:[NSDate date]];
        break;

}

2

Khai báo các biến bên ngoài công tắc, sau đó khởi tạo chúng trong trường hợp. Điều đó làm việc hoàn hảo với tôi khi sử dụng Xcode 6.2


1
default:
        CellIdentifier = @"Cell";
        cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            ***initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];***
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            }
        break;
    }

Lưu ý: Kiểm tra! Cú pháp của dòng in đậm & in nghiêng. Khắc phục nó và bạn tốt để đi.


0

Bao quanh với dấu ngoặc {}giữa mã trường hợp và dấu ngắt trong mỗi trường hợp. Nó hoạt động trên mã của tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.