2009-06-03 21 views

Trả lời

27

OS X 10.6 đã giới thiệu các khối. Xem AlBlue's answer for examples.

Nếu bạn không sử dụng Snow Leopard, bạn có thể nhận được thứ gì đó gần với bố cục chức năng bằng nhiều tính năng khác.

Ví dụ sử dụng C con trỏ hàm:

void sayHello() { 
    NSLog(@"Hello!"); 
} 

void doSomethingTwice(void (*something)(void)) { 
    something(); 
    something(); 
} 

int main(void) { 
    doSomethingTwice(sayHello); 
    return 0; 
} 

Ví dụ sử dụng mô hình lệnh:

@protocol Command <NSObject> 
- (void) doSomething; 
@end 

@interface SayHello : NSObject <Command> { 
} 
@end 

@implementation SayHello 
- (void) doSomething { 
    NSLog(@"Hello!");  
} 
@end 

void doSomethingTwice(id<Command> command) { 
    [command doSomething]; 
    [command doSomething]; 
} 

int main(void) { 
    SayHello* sayHello = [[SayHello alloc] init]; 
    doSomethingTwice(sayHello); 
    [sayHello release]; 
    return 0; 
} 

Ví dụ sử dụng một selector:

@interface SaySomething : NSObject { 
} 
- (void) sayHello; 
@end 

@implementation SaySomething 
- (void) sayHello { 
    NSLog(@"Hello!");  
} 
@end 

void doSomethingTwice(id<NSObject> obj, SEL selector) { 
    [obj performSelector:selector]; 
    [obj performSelector:selector]; 
} 

int main(void) { 
    SaySomething* saySomething = [[SaySomething alloc] init]; 
    doSomethingTwice(saySomething, @selector(sayHello)); 
    [saySomething release]; 
    return 0; 
} 
+1

Điều này có thể đã đúng trước đó, nhưng ngôn ngữ hiện có các khối, cho phép bạn xác định các biểu thức lambda thực. Có nói rằng, có thể vượt qua xung quanh @selector() s như mô tả ở trên là một cơ chế thực sự hữu ích trong bộ công cụ Objective-C. – AlBlue

+1

-1 vì thiếu thông tin về khối, tính năng mới trung tâm, có sẵn trong C, ObjC và C++ khi sử dụng GCC của Apple trong phiên bản 10.6 mới của OS X. – harms

+0

+1 để cung cấp các mẫu thiết kế có thể thích hợp hơn các khối trong một số tình huống. – user2398029

3

tôi nghe André Pang tại NSConference nói về cách khối sẽ được giới thiệu với phiên bản tiếp theo của Objective-C.

Điều này sẽ cho phép lập trình chức năng.

Chỉnh sửa: Vì Snow Leopard đã được phát hành, đây thực sự là trường hợp. Mục tiêu-C hiện có Blocks.

87

Khái niệm về lambda trong Mục tiêu-C hiện được đóng gói với ý tưởng Blocks tương đương với hàm truyền qua tham chiếu. Tất nhiên, được cho là đã có trong C với ý tưởng về các con trỏ hàm; các khối chỉ là một cách để nắm bắt trạng thái cục bộ (tức là có thể bị đóng). Trong thực tế, các khối cũng có thể được sử dụng trong các ngôn ngữ C khác (trên Mac) - có một đề xuất để làm cho chúng trở thành một phần của cú pháp C chuẩn.

Dưới đây là một ví dụ về việc xác định một lambda để nhân hai số với nhau:

int (^mult)(int, int) = ^(int a, int b) { return a*b; }; 

Phần đầu tiên khai báo một biến, các loại ^int(int,int) và sau đó gán nó vào biểu thức lambda (aka khối) mà trả về nhiều của hai đối số của nó. Sau đó bạn có thể vượt qua fn đó, xác định nó ở những nơi khác vv; bạn thậm chí có thể sử dụng nó trong các chức năng khác.

Dưới đây là một ví dụ về việc xác định một chức năng, mà khi gọi, trả về chức năng khác:

multiplyBy = ^(int a) { return ^(int b) { return b*a; }; }; 
triple = multiplyBy(3); 

Lưu ý rằng bạn có thể intermix khối với các loại đối tượng (thường sử dụng id như các loại đối tượng) và rất nhiều các mới Cấu trúc dữ liệu đối tượng-Objective-C có một số loại hoạt động cấp khối. GCD cũng sử dụng các khối để truyền vào các sự kiện tùy ý; tuy nhiên, lưu ý rằng GCD cũng có thể được sử dụng với các con trỏ hàm.

+0

+1 để có câu trả lời chi tiết. – Abizern

+0

Cũng lưu ý rằng hỗ trợ chặn đã được chuyển đến 10.5 và hệ điều hành iPhone với dự án Plausible Blocks. http://code.google.com/p/plblocks/ – Chuck

+1

Lưu ý rằng các khối có thể được sử dụng trong iOS 4, không có dự án Plausible Blocks. –

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