2010-07-15 34 views
36

Tôi đã suy nghĩ, vì bạn có thể xử lý các khối như đối tượng nếu tôi tạo hai trong số chúng và sau đó thêm chúng vào một NSArray là có một cách để thực hiện chúng từ mảng?Thực thi các khối từ NSArray?

int (^Block_001)(void) = ^{ return 101; }; 
int (^Block_002)(void) = ^{ return 202; }; 
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil]; 

EDIT: Cập nhật cho rõ ràng mỗi câu trả lời tuyệt vời @ davedelong của

int (^Block_001)(void) = [^{ return 101; } copy]; 
int (^Block_002)(void) = [^{ return 202; } copy]; 
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil]; 

[Block_001 release]; 
[Block_002 release]; 
+2

Tập hợp các câu trả lời tuyệt vời .... Tôi thấy tiêu đề và hy vọng một số điểm đại diện dễ dàng. Folks đã nhận nó hoàn toàn được bảo hiểm. :) – bbum

+0

Chỉ cần một điểm nhanh, nếu bạn không sao chép/phát hành các khối sẽ được trong ngăn xếp ... Vì vậy, nếu ngăn xếp bị phá hủy các ứng dụng sẽ sụp đổ phải không? – fzaziz

Trả lời

29

Chắc chắn, bạn chỉ cần gọi nó với () giống như bất kỳ khối khác, nhưng bạn cần phải định kiểu giá trị mà bạn lấy từ NSArray. Dưới đây là một ví dụ (với một typedef thêm, bởi vì nếu không đầu tôi đau):

typedef int (^IntBlock)(void); 
IntBlock Block_001 = ^{ return 101; }; 
IntBlock Block_002 = ^{ return 202; }; 
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil]; 
int x = ((IntBlock)[array objectAtIndex:0])(); // now x == 101 
+0

ok, do đó, không quen thuộc với các con trỏ hàm tôi có nhận được quyền này không? Typedef định nghĩa "IntBlock" là một con trỏ tới một khối trả về một int và không có đối số. Tôi nghĩ rằng tôi nhận được nó, và nhìn vào thay thế (mà tôi khá chắc chắn tôi sẽ nhận được sai) Tôi đánh giá cao quyết định của bạn để đi với typedef :) Nhiều đánh giá cao. – fuzzygoat

+0

Có, bạn đã có nó. –

+1

Bạn không cần phải truyền. Nó hoạt động tốt để làm 'int (^ block)() = [mảng objectAtIndex: 0]'. Một con trỏ là một con trỏ là một con trỏ, sau khi tất cả, ít nhất là trong các ngôn ngữ cấp thấp như 'C' và các dẫn xuất của nó. – aroth

6

Tất nhiên bạn có thể.

int (^x)(void) = [array objectAtIndex:0]; 
printf("%d\n", x()); // prints 101. 
+0

Tôi đã xem xét điều này, rất thú vị. Bạn có thể chỉ cần làm rõ cho tôi, tôi phải trong đề cập đến "int (^ x) (void)" như một con trỏ đến một khối? Chỉ cần cố gắng để đảm bảo rằng tôi nhận được thuật ngữ chính xác. – fuzzygoat

60

@KennyTM và @ David là chính xác, nhưng mã của bạn là có khả năng sai. Đây là lý do:

Khi tạo một NSArray với các đối tượng, nó sẽ retain các đối tượng được đưa vào đó. Trong trường hợp các khối, nó đang sử dụng hàm Block_retain. Điều này có nghĩa là mảng đã giữ lại các khối mà bạn đã tạo, nhưng sống trên ngăn xếp (các khối là một trong những ví dụ rất hiếm của các đối tượng Objective-C có thể được tạo trên ngăn xếp mà không cần giải quyết các thủ thuật vô lý). Điều đó có nghĩa là ngay khi phương pháp này thoát, mảng của bạn hiện trỏ đến thùng rác, bởi vì các khối mà nó trỏ đến không còn tồn tại. Để làm điều này đúng cách, bạn nên làm:

int (^Block_001)(void) = [^{ return 101; } copy]; 
int (^Block_002)(void) = [^{ return 202; } copy]; 
NSArray *array = [NSArray arrayWithObjects:Block_001, Block_002, nil]; 

[Block_001 release]; 
[Block_002 release]; 

Bằng cách gọi copy trên block, bạn đang di chuyển một cách rõ ràng khối tắt của ngăn xếp và lên đống, nơi nó có thể yên tâm còn lại sau khi các phương pháp/thoát chức năng . Sau đó, sau khi bạn đã thêm các khối vào mảng, bạn phải cân bằng copy (vì quy tắc NARC) với lệnh gọi tiếp theo là release. Có lý?

+0

Xin chào Dave, vâng tôi hiểu, tôi không biết các khối được tạo ra trên ngăn xếp (chỉ mới bắt đầu xem xét các khối ngày hôm nay). Nhiều đánh giá cao. – fuzzygoat

+0

Điểm tuyệt vời khi cần phải sao chép –

+0

Xin chào Dave, tôi đã tìm thấy câu hỏi này và câu trả lời được chấp nhận của David Gelhar vì vậy tôi đã thực hiện nó và nó hoạt động khá tốt, nó không ** bị hỏng. Đọc thêm, câu trả lời của bạn có ý nghĩa nhưng không giải thích tại sao mã của david không bị rơi (ngay lập tức?). Bạn có chút manh mối nào không? – Tieme

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