Hôm nay tôi đã thử nghiệm với khối Objective-C vì vậy tôi nghĩ rằng tôi muốn được thông minh và thêm vào NSArray một vài phương pháp thu thập chức năng theo phong cách mà tôi đã nhìn thấy trong các ngôn ngữ khác:Sử dụng Objective-C Khối
@interface NSArray (FunWithBlocks)
- (NSArray *)collect:(id (^)(id obj))block;
- (NSArray *)select:(BOOL (^)(id obj))block;
- (NSArray *)flattenedArray;
@end
Phương pháp thu thập: phương thức lấy một khối được gọi cho mỗi mục trong mảng và dự kiến trả về kết quả của một số thao tác sử dụng mục đó. Kết quả là tập hợp tất cả các kết quả đó. (Nếu khối trả về nil, không có gì được thêm vào tập kết quả.)
Phương thức select: sẽ trả về một mảng mới chỉ với các mục từ bản gốc, khi được chuyển làm đối số cho khối, khối được trả về VÂNG.
Và cuối cùng, phương thức flattenedArray lặp lại trên các mục của mảng. Nếu một mục là một mảng, nó đệ quy gọi flattenedArray trên nó và thêm kết quả vào tập kết quả. Nếu mục không phải là mảng, nó sẽ thêm mục vào tập kết quả. Tập kết quả được trả về khi mọi thứ kết thúc.
Vì vậy, bây giờ tôi đã có một số cơ sở hạ tầng, tôi cần một trường hợp thử nghiệm. Tôi quyết định tìm tất cả các tệp gói trong thư mục ứng dụng của hệ thống. Đây là những gì tôi đã đưa ra:
NSArray *packagePaths = [[[NSSearchPathForDirectoriesInDomains(NSAllApplicationsDirectory, NSAllDomainsMask, YES) collect:^(id path) { return (id)[[[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil] collect:^(id file) { return (id)[path stringByAppendingPathComponent:file]; }]; }] flattenedArray] select:^(id fullPath) { return [[NSWorkspace sharedWorkspace] isFilePackageAtPath:fullPath]; }];
Đúng - đó là tất cả một dòng và nó kinh khủng. Tôi đã thử một vài cách tiếp cận để thêm các dòng mới và thụt đầu dòng để cố gắng dọn dẹp nó, nhưng nó vẫn cảm thấy như thuật toán thực tế bị mất trong tất cả các nhiễu. Tôi không biết nếu nó chỉ là một điều cú pháp hoặc người thân của tôi trong kinh nghiệm với việc sử dụng một phong cách chức năng đó là vấn đề, mặc dù.
Để so sánh, tôi quyết định làm điều đó "theo cách cũ thời" và chỉ sử dụng các vòng lặp:
NSMutableArray *packagePaths = [NSMutableArray new];
for (NSString *searchPath in NSSearchPathForDirectoriesInDomains(NSAllApplicationsDirectory, NSAllDomainsMask, YES)) {
for (NSString *file in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:searchPath error:nil]) {
NSString *packagePath = [searchPath stringByAppendingPathComponent:file];
if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:packagePath]) {
[packagePaths addObject:packagePath];
}
}
}
IMO phiên bản này là dễ dàng hơn để viết và dễ đọc hơn để khởi động.
Tôi cho rằng có thể đây là một ví dụ xấu, nhưng có vẻ như đó là cách hợp pháp để sử dụng các khối đối với tôi. (Tôi có sai?) Tôi có thiếu một cái gì đó về cách viết hoặc cấu trúc mã Objective-C với các khối sẽ làm sạch điều này và làm cho nó rõ ràng hơn (hoặc thậm chí chỉ là rõ ràng như) phiên bản looped?
đẹp giải pháp, mặc dù tôi không phải là một fan hâm mộ lớn của định nghĩa lại 'paths' nhiều lần. Tôi có lẽ sẽ kết thúc đặt tên một vài giá trị dựa trên nội dung của chúng và kết thúc với một giá trị được gọi là 'đường dẫn'. Chỉ cần hai xu của tôi. –
Hoạt ảnh UIView sử dụng 2 khối. –
Ông cho biết mô hình không phải là kinh điển. Những phương thức thực hiện nhiều khối tất cả đều có các khối như các tham số cuối cùng. Ngoài ra, các API đó đã xuất hiện trong iOS 4, đã lâu sau bài đăng này. – logancautrell