2011-10-13 36 views
6

Hãy xem xét các đoạn mã sau:Blocks, vòng lặp và biến cục bộ

for(/* some condition */) { 
    int x = rand(); 
    [array addObject:^(){ 
     NSLog(@"%d", x); 
    }] 
} 

for(void (^block)() in array) { 
    block(); 
} 

Bây giờ tôi mong chờ đoạn mã này để in ra tất cả các giá trị được gán cho x ở chỗ cho vòng lặp; tuy nhiên có vẻ như tất cả các khối chia sẻ cùng một biến 'x' (có lẽ là biến cuối cùng).

Bất kỳ ý tưởng nào tại sao điều này là như vậy và cách tôi có thể sửa mã để mỗi khối chứa biến 'x' như lúc đó khối đã được xác định?

+0

Tôi vẫn tự học hỏi về bản thân nhưng một điều kỳ lạ xuất hiện trong đầu. Khi bạn addObject :, mảng sẽ mặc định giữ lại đối tượng khối. Tuy nhiên, khối đối tượng được đặt trên ngăn xếp khi chúng được khai báo để nó có vẻ như ở đây họ sẽ ngay lập tức rơi ra khỏi phạm vi. Block_Copy sẽ di chuyển khối đến heap mà có vẻ như điều phải làm. –

Trả lời

7

Tài liệu cụ thể says not to do this. Lý do là các khối được phân bổ trên ngăn xếp, có nghĩa là chúng có thể nằm ngoài phạm vi. Vì lý do tương tự, bạn không thể truy cập biến số x bên ngoài vòng lặp for đầu tiên, bạn cũng không nên sử dụng khối đó. x đã vượt quá phạm vi, cùng với chính khối đó và có thể chứa bất kỳ giá trị nào.

Để làm được việc này, bạn có thể mất một bản sao của khối như sau:

for(/* some condition */) { 
    int x = rand(); 
    void(^logBlock)() = ^() { NSLog(@"%d", x); } 
    [array addObject:[[logBlock copy] autorelease]]; 
} 

này di chuyển khối vào heap, và nên khắc phục vấn đề của bạn.

Các vấn đề liên quan