2011-12-02 25 views
9

Ok, vì vậy tôi hiểu làm thế nào để tránh self giữ lại chu kỳ với các khối, làm thế nào về trường hợp khi tôi gửi một thông điệp tới tự từ một phương pháp trong một khối lồng nhau sâu sắc hơn trong cuộc gọi stack như thế này:Blocks và tự từ gọi là phương pháp

- (void)methodA { 
    __block MyClass *blockSelf = self; 
    [someObject block:^{ 
     [blockSelf methodB]; 
    }]; 
} 

- (void)methodB { 
    ... 
    [self methodC]; 
    ... 
} 

- (void)methodC { 
} 

Trong trường hợp này [blockSelf methodB] là tốt, nhưng đang gửi [self methodC] từ methodB gây ra chu kỳ lưu giữ hay không? Không thể tìm thấy câu trả lời ở bất kỳ nơi nào ...

Trả lời

8

Không có chu kỳ lưu giữ ở đó. Khi một khối chữ được định nghĩa bên trong một phương pháp, bối cảnh có thể được chụp bởi khối được giới hạn trong những gì là có thể nhìn thấy bên trong phương pháp đó. Trong ví dụ của bạn:

- (void)methodA { 
    __block MyClass *blockSelf = self; 
    [someObject block:^{ 
     [blockSelf methodB]; 
    }]; 
} 

the Block đen, cụ thể là:

^{ 
    [blockSelf methodB]; 
} 

có thể thấy như sau:

  1. self_cmd, được giấu các thông số có sẵn trong mỗi Mục tiêu -C phương pháp. Nếu -methodA có các tham số chính thức, Khối theo nghĩa đen sẽ có thể xem chúng;
  2. Bất kỳ biến phạm vi khối nào bên trong khối chức năng/phương thức, tức là mọi biến cục bộ bên trong phương thức và được hiển thị tại điểm có nghĩa là khối chữ được xác định. Trong ví dụ này, biến cục bộ duy nhất bên trong -methodAblockSelf, vì đó là __block -qualified, không được giữ lại;
  3. Bất kỳ biến phạm vi tệp nào (còn gọi là biến toàn cục).

Một khối chữ không biết (và, trong trường hợp chung, không thể biết) về những gì xảy ra bên trong các hàm/phương pháp khác, do đó bất kỳ ngữ cảnh nào có sẵn bên trong hàm/phương thức được gọi là Bạn chỉ cần lo lắng về phương thức mà Block literal được định nghĩa.

Tôi đang sử dụng ước của Apple tận Khối khi đề cập đến việc đóng cửa/lambdas (ví dụ: ^{}) và khối chữ thường khi đề cập đến C khối (ví dụ: {}).

+0

Tuyệt vời, cảm ơn! Điều này sẽ loại bỏ một loạt các "thông số hacks" xấu xí từ các phương thức trợ giúp của tôi ... – Tom

+0

"Không có chu kỳ giữ lại ở đó." tốt, nó phụ thuộc vào 'someObject' là gì và liệu nó có giữ lại khối được truyền cho nó hay không. Nếu 'self' giữ lại' someObject' (ví dụ, nó là một biến cá thể), và nếu 'someObject' lưu trữ và giữ lại khối được truyền vào' block: ', thì sẽ có một chu trình giữ lại. – newacct

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