Sea*_*ean 17 coding-style objective-c
今天我正在试验Objective-C的块,所以我觉得我很聪明,并在NSArray中添加了一些我在其他语言中看到的功能风格的收集方法:
@interface NSArray (FunWithBlocks)
- (NSArray *)collect:(id (^)(id obj))block;
- (NSArray *)select:(BOOL (^)(id obj))block;
- (NSArray *)flattenedArray;
@end
Run Code Online (Sandbox Code Playgroud)
collect:方法接受一个为数组中的每个项调用的块,并期望使用该项返回某些操作的结果.结果是收集所有这些结果.(如果块返回nil,则不会向结果集添加任何内容.)
select:方法将返回一个只包含原始项的新数组,当作为参数传递给块时,块返回YES.
最后,flattenedArray方法迭代数组的项目.如果一个项是一个数组,它会递归调用flattenedArray并将结果添加到结果集中.如果该项不是数组,则将该项添加到结果集中.一切都完成后返回结果集.
所以现在我有了一些基础设施,我需要一个测试用例.我决定在系统的应用程序目录中找到所有包文件.这就是我想出的:
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]; }];
Run Code Online (Sandbox Code Playgroud)
是的 - 这一切都是一线而且很可怕.我尝试了一些方法来添加换行符和缩进以尝试清理它,但它仍然感觉实际算法在所有噪声中都丢失了.不过,我不知道这只是一种语法问题,还是我使用功能风格的亲戚体验.
为了比较,我决定采用"老式的方式"并使用循环:
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];
}
}
}
Run Code Online (Sandbox Code Playgroud)
IMO这个版本更易于编写,并且更易于启动.
我想这可能是一个不好的例子,但它似乎是一种使用块的合法方式.(我错了?)我是否遗漏了一些关于如何使用块来编写或构造Objective-C代码的东西,这些块可以清理它并使其比循环版本更清晰(甚至更清晰)?
bbu*_*bum 19
使用换行符并跨多行分手.
所有Apple API使用的标准模式是方法或函数应该只接受一个块参数,并且该参数应该始终是最后一个参数.
你做了什么.好.
现在,在编写使用所述API的代码时,请执行以下操作:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSAllApplicationsDirectory, NSAllDomainsMask, YES);
paths = [paths collect: ^(id path) {
...
}];
paths = [paths collect: ^(id path) {
...
}];
paths = [paths select: ^(id path) {
...
}];
Run Code Online (Sandbox Code Playgroud)
即你的收集/选择/过滤/展平/地图/每一步作为一个单独的步骤.这将不会比链式方法调用更快/更慢.
如果你确实需要在块的一侧嵌套块,那么在完全缩进的情况下执行此操作:
paths = [paths collect: ^(id path) {
...
[someArray select:^(id path) {
...
}];
}];
Run Code Online (Sandbox Code Playgroud)
就像嵌套的if语句之类.当它变得太复杂时,根据需要将其重构为函数或方法.
| 归档时间: |
|
| 查看次数: |
15620 次 |
| 最近记录: |