2011-10-31 22 views
5

Lợi ích hiệu suất của trình biên dịch (cụ thể là các trình biên dịch mà Xcode sử dụng) không xử lý mọi biến dưới dạng biến __block? Tôi tưởng tượng rằng phải có một cái gì đó, tôi nghi ngờ rằng trong quan niệm của biến __block nó đã được quyết định rằngLý do gì mà trình biên dịch sẽ không xử lý mọi biến dưới dạng biến __block?

__block SelfClass * blockSelf = self; 

là cú pháp tốt và thuận tiện.

Trả lời

4

Mục tiêu của các khối là làm cho nó tự động và minh bạch nhất có thể để sử dụng các khối có cú pháp tối thiểu và yêu cầu chúng "chỉ hoạt động".

Biến Non -__ khối, làm mặc định, là nhiều hơn nữa phù hợp với khái niệm "đóng cửa" mà khối đại diện. Một snapshot khối trạng thái của tất cả các biến được tham chiếu trong khối tại thời điểm thực hiện chuyển qua khai báo khối. Điều này bao gồm cả việc sao chép bộ nhớ/trạng thái và giữ lại bất kỳ tham chiếu đối tượng Objective-C nào được capture trong khối.

__block phá vỡ hiệu quả việc đóng gói trạng thái trong khối. Rất hữu ích, nhưng yêu cầu quản lý thủ công các tham chiếu đối tượng trên một phần của lập trình viên.

I.e. biến số không `block 'chỉ hoạt động" thường xuyên hơn các biến __block và, do đó, hành vi mặc định là bị hút "chỉ hoạt động".

Trong thực tế, chi phí chụp trạng thái trong một khối thường nhỏ nhất. Tác động có thể đo lường về hiệu suất ứng dụng thường hiếm và thường chỉ ra một vấn đề kiến ​​trúc có tính chất sâu sắc hơn.


Nếu theo:

__block SelfClass * blockSelf = self; 

Bạn đang đề cập trên thập tự giá sản phẩm phụ của Khối và ARC? Vâng, đó là một chút không may. Nhưng trình biên dịch cũng cảnh báo về một vấn đề rất thực tế mà bạn cần phải biết. Tuy nhiên, một cách giải quyết rõ ràng hơn sẽ rõ ràng là thích hợp hơn.

0

__block có thể tồn tại sự hủy diệt ngăn xếp. Điều này sẽ chỉ đáng chú ý với các biến có phạm vi C++:

{ 
    __block shared_ptr<A> ptr = make_shared(new A); 
    self.some_block = ^(void){}; 
} // ptr will not be deleted until the block is destructed 
{ 
    shared_ptr<A> ptr = make_shared(new A); 
    self.some_block = ^(void){}; 
} // ptr will be deleted here 

Nó cũng đáng chú ý với việc thu gom rác nhưng ít đáng chú ý và khó ví dụ hơn.

+0

Không hoàn toàn; trong cả hai trường hợp, khối là khối ngăn xếp chồng và do đó, sẽ bị hủy với phạm vi. Bạn phải sao chép khối để làm cho nó tồn tại trong phạm vi. Đồng thời, đây chỉ là một chi tiết nhỏ của '__block'; có chiến tranh nhiều yếu tố lái xe khác. – bbum

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