2012-05-03 17 views
9

Chỉ cố gắng xử lý các khối. Tôi có khái niệm. Chúng giống như các con trỏ hàm, nhưng chúng thực sự là các đối tượng; bạn có thể khai báo một biến khối và gán cho nó một giá trị khối; gọi nó như một hàm; chúng bị "đóng băng trong thời gian", vì thiếu một thuật ngữ, khi chúng được thực hiện, vv Tôi đã tạo ra một vài khối và chạy chúng thành công, trong một vài định dạng khác nhau, nhưng khi nói đến việc sử dụng chúng trong một phương thức - dù bằng typedef hay không - Tôi gặp rất nhiều rắc rối. Ví dụ, đây là một giao diện đối tượng tôi tạo ra, chỉ để có được một xử lý trên cú pháp. Tôi gần như không có ý tưởng làm thế nào để thực hiện nó.Mục tiêu-C: typedef'd một khối, sử dụng nó trong một tuyên bố phương pháp. Làm thế nào để tôi thực hiện điều này?

// AnObject.h 

#import <Foundation/Foundation.h> 

// The idea with the block and the method below is for the block to take 
// an int, multiply it by 3, and return a "tripled" int. The method 
// will then repeat: this process however many times the user wants via 
// the howManyTimes parameter and return that value in the form of an int. 

typedef int (^triple)(int); 

@interface AnObject : NSObject 
{ 
    int num; 
} 

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock; 

@end 

Dưới đây là những gì tôi có cho một thực hiện, cho đến nay:

#import "AnObject.h" 

@implementation AnObject 

@synthesize num; 

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock { 
    for (int i = 0; i <= howManyTimes; i++) { 
     // What the heck am I supposed to put here? I'm baffled by the 
     // syntax over and over again. 
    } 
} 

@end 

tôi biết tôi không giải quyết các biến dụ được nêu ra. Một lần nữa, đây là một bản thảo thô, chỉ cố gắng để có được một xử lý về cách khối làm việc. Tôi thậm chí còn tuyên bố phương pháp này đúng không? Tôi đang đọc Lập trình Mục tiêu-C của trang trại Big Nerd, bài viết của Mike Clark về các khối từ Pragmatic Studio và một vài chủ đề SO. Không thể tìm thấy bất cứ điều gì có liên quan. Cảm ơn.

EDIT: XCode 4.3.2, nếu nó quan trọng.

THÊM CHỈNH SỬA: Ok. Sử dụng (sửa đổi đôi chút) ví dụ BJ, tôi nghĩ rằng tôi đã tìm ra một cách thực sự phức tạp của nhân 5 bằng 3. :)

// BJ's implementation: 

-(int)repeat:(int)howManyTimes withBlock:(Triple)someBlock { 

    int blockReturnValue; 

    for (int i = 0; i <= howManyTimes; i++) { 
     blockReturnValue = someBlock(i); 
    } 
    return blockReturnValue; 
} 

chính:

... 
    @autoreleasepool 
    { 
     AnObject *obj = [[AnObject alloc] init]; 

     NSLog(@"%d", [obj repeat: 5 withBlock:^(int number) { 
      return number * 3; 
     }]); 

    } 
    return 0; 
... 

Và kết quả là:

15 

Bây giờ, nó khởi động lại 15, vì khối tôi đã xác định làm đối số chỉ chạy một lần, phải không? Nó nhân "số", là 5 trong trường hợp này, bằng 3 và đóng băng câu trả lời đó, đúng không? Tôi chắc rằng tôi vừa tạo ra một phương pháp hoàn toàn vô dụng và tôi chưa hiểu cách sử dụng các lợi ích/tính năng của một khối. Tôi có đúng không?

/* ** * ** * ** * ** * ** * ** * ** CẬP NHẬT ** * ** * ** * ** * ** * ** * ** */

UPDATE: Tôi hiểu những gì bạn đang nói, CRD. Mặc dù vậy, chỉ cần một sự điều chỉnh, đối với bất kỳ lập trình viên mới nào có thể đọc được điều này, nhận được một đầu ra khác và đi, "Quế?" cho vòng lặp của bạn nên là một trong hai:

for (int i = 0; i < howManyTimes; i++) 
      value = someBlock(value); 

... hoặc ...

(i = 1; i <= howManyTimes; i++) 

... để có được những câu trả lời 243.

Và, vâng, đây chính xác là những gì tôi ban đầu đang cố gắng thực hiện với mã này. Ít nhất đó là những gì tôi nghĩ là đáng lẽ phải xảy ra. Hóa ra ý định của tác giả không phải là gấp ba số, lưu trữ giá trị đó, gấp ba giá trị được lưu trữ, lưu trữ ... vv mà chỉ để in x * 3 cho số 1-5 (3, 6, 9, 12, 15).

Đây là sản phẩm đã hoàn thành. Tôi chỉ cần gõ một khối mà có một int và trả về một int, được gọi là Tripler. Tôi cũng thay đổi tên của đối số từ "someBlock" thành "triple" để cho biết rõ hơn mục đích sử dụng của khối. Tôi nghĩ đó là những thay đổi duy nhất đối với mã.

/******************** interface ********************/ 


#import <Foundation/Foundation.h> 

typedef int (^Tripler)(int); 

@interface AnObject : NSObject 

-(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple; 

@end 

/******************** implementation ********************/ 


#import "AnObject.h" 

@implementation AnObject 

-(void)iterateFromOneTo:(int)number withBlock:(Tripler)triple { 
    for (int i = 1; i <= number; i++) { 
     NSLog(@"%d", triple(i)); 
    } 
} 

@end 

/******************** main.m ********************/ 


#import "AnObject.h" 
#import <Foundation/Foundation.h> 

int main(int argc, const char * argv[]) 
{ 
    @autoreleasepool 
    { 
     AnObject *obj = [[AnObject alloc] init]; 

     [obj iterateFromOneTo:5 withBlock:^(int number) { 
      return number * 3; 
     }]; 
    } 
    return 0; 
} 

Như bạn có thể tưởng tượng, kết quả đầu ra là:

2012-05-05 17:10:13.418 Untitled 2[71735:707] 3 
2012-05-05 17:10:13.445 Untitled 2[71735:707] 6 
2012-05-05 17:10:13.446 Untitled 2[71735:707] 9 
2012-05-05 17:10:13.446 Untitled 2[71735:707] 12 
2012-05-05 17:10:13.447 Untitled 2[71735:707] 15 

tôi đã làm cho nó rất nhiều phức tạp hơn nó cần thiết để được. Xin lỗi vì đã giải thích nó quá kém trong OP. Cảm ơn bạn đã giúp đỡ!/chủ đề? :)

+0

Đi qua khối giải thích này ... http://www.highoncoding.com/Articles/852_Introduction_to_Objective_C_Blocks.aspx – shankar

Trả lời

7

Chỉ cần gọi khối như chức năng C thông thường.

-(int)repeat:(int)howManyTimes withBlock:(triple)someBlock { 
    for (int i = 0; i <= howManyTimes; i++) { 
     int blockReturnValue = someBlock(i); 
     // do something with blockReturnValue 
    } 
} 

Cập nhật sau khi "chỉnh sửa thêm" bạn

Không, khối bạn thông qua tại như một cuộc tranh cãi đang chạy năm lần, mỗi lần đi qua vòng lặp for.

  • Lần đầu tiên, nó gọi khối bằng số 1 làm đối số và quay lại 3. Nó lưu trữ trong blockReturnValue, sau đó chuyển sang vòng lặp tiếp theo của vòng lặp.
  • Lần thứ hai, nó gọi khối với số đối số 2 và quay lại 6. Nó lưu trữ rằng trong blockReturnValue, ghi đè hoàn toàn giá trị mà chúng tôi đã lưu trữ ở thẻ trước đó.
  • Lần thứ ba, nó sẽ chặn khối với đối số 3 và quay lại 9. Một lần nữa, nó ghi đè lên giá trị trong blockReturnValue.
  • Lần thứ tư, chúng tôi lưu trữ 12 trong blockReturnValue.
  • Lần thứ năm, chúng tôi lưu trữ 15 trong blockReturnValue.

Sau đó, chúng tôi thoát khỏi vòng lặp for và trả lại 15. Vì vậy, đúng là bạn đã thực hiện một phương pháp vô nghĩa để nhân với 3. Nhưng bạn đang thực hiện nó theo cách thực hiện loạt các tính toán vô dụng.

+0

Được rồi. Có lẽ nó đơn giản hơn tôi đang làm cho nó ra được. Làm việc trên đó ngay bây giờ. – baptzmoffire

+0

Ok. Xin vui lòng xem "THÊM EDIT:" Cảm ơn sự giúp đỡ, BJ. – baptzmoffire

+1

Tôi nghĩ rằng tôi có chỉ số IQ lập trình thấp. : P Tôi nhận được ý chính của những gì đang xảy ra. Nó phải rõ ràng hơn, nhưng nó chỉ là cú pháp cho tôi phù hợp, tôi đoán vậy. Đó là điều khiến tôi không thể theo dõi những gì đang diễn ra. Tôi sẽ ăn nhiều khối nhất có thể cho đến khi cuối cùng tôi xem chúng hoạt động như thế nào và khi nào thì sử dụng chúng đúng cách. Cảm ơn rất nhiều vì sự giúp đỡ và kiên nhẫn của bạn. – baptzmoffire

8

Từ đọc câu hỏi của bạn tôi hiểu hoặc có thể bị hiểu lầm, ý định của bạn là tạo ra kết quả áp dụng khối của bạn n lần; ví dụ. nếu bạn áp dụng hàm ba lần hai lần, bạn sẽ nhận được giá trị ban đầu nhân với 9.

Chỉ trong trường hợp nó giúp, đây là đoạn code để làm điều đó:

@interface AnObject 

typedef int (^monadic)(int); // an function which takes an int and return an int 

- (int) repeat:(int)howManyTimes for:(int)value withBlock:(monadic)someBlock; 

@end 

@implementation AnObject 

- (int) repeat:(int)howManyTimes for:(int)value withBlock:(monadic)someBlock 
{ 
    for (int i = 0; i < howManyTimes; i++) 
     value = someBlock(value); 

    return value; 
} 

@end 

Bây giờ gọi này với:

AnObject *myObject = [AnObject new]; 

int z = [myObject repeat:5 
        for:1 
       withBlock: ^(int number) 
          { 
          return number * 3; 
          } 
     ]; 

z sẽ có giá trị 243.

+0

Cảm ơn bạn đã phản hồi, CRD. Đánh giá cao bạn lấy lại thời gian. Xem "UPDATE" ở trên. – baptzmoffire

+0

@baptzmoffire - chính xác, oops :-(sửa lỗi đánh máy, bây giờ nó tạo ra 243! – CRD

+0

Cảm ơn một lần nữa, CRD. :) – baptzmoffire

1
@import Foundation; 

typedef int(^MyBlockType)(int); 

@implementation NSObject(extra) 
+ (int)invokeBlock:(MyBlockType)block withArgument:(int)arg 
{ 
    return block(arg); 
} 
@end; 

int main() { 
    @autoreleasepool { 
     NSLog(@"executeBlock(3) returns %d", 
       [NSObject invokeBlock:^(int param) { return param * param; } withArgument:3]); 
    } return 0; 
} 
Các vấn đề liên quan