Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 375081
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T14:28:05+00:00 2026-05-12T14:28:05+00:00

Today I was experimenting with Objective-C’s blocks so I thought I’d be clever and

  • 0

Today I was experimenting with Objective-C’s blocks so I thought I’d be clever and add to NSArray a few functional-style collection methods that I’ve seen in other languages:

@interface NSArray (FunWithBlocks)
- (NSArray *)collect:(id (^)(id obj))block;
- (NSArray *)select:(BOOL (^)(id obj))block;
- (NSArray *)flattenedArray;
@end

The collect: method takes a block which is called for each item in the array and expected to return the results of some operation using that item. The result is the collection of all of those results. (If the block returns nil, nothing is added to the result set.)

The select: method will return a new array with only the items from the original that, when passed as an argument to the block, the block returned YES.

And finally, the flattenedArray method iterates over the array’s items. If an item is an array, it recursively calls flattenedArray on it and adds the results to the result set. If the item isn’t an array, it adds the item to the result set. The result set is returned when everything is finished.

So now that I had some infrastructure, I needed a test case. I decided to find all package files in the system’s application directories. This is what I came up with:

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]; }];

Yep – that’s all one line and it’s horrid. I tried a few approaches at adding newlines and indentation to try to clean it up, but it still feels like the actual algorithm is lost in all the noise. I don’t know if it’s just a syntax thing or my relative in-experience with using a functional style that’s the problem, though.

For comparison, I decided to do it “the old fashioned way” and just use loops:

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 this version was easier to write and is more readable to boot.

I suppose it’s possible this was somehow a bad example, but it seems like a legitimate way to use blocks to me. (Am I wrong?) Am I missing something about how to write or structure Objective-C code with blocks that would clean this up and make it clearer than (or even just as clear as) the looped version?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-12T14:28:05+00:00Added an answer on May 12, 2026 at 2:28 pm

    Use newlines and break up your call across multiple lines.

    The standard pattern used across all of Apple’s APIs is that a method or function should only take one block argument and that argument should always be the last argument.

    Which you have done. Good.

    Now, when writing the code that uses said API, do something like:

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSAllApplicationsDirectory, NSAllDomainsMask, YES);
    paths = [paths collect: ^(id path) {
        ...
    }];
    paths = [paths collect: ^(id path) {
        ...
    }];
    paths = [paths select: ^(id path) {
        ...
    }];
    

    I.e. do each step of your collect/select/filter/flatten/map/whatever as a separate step. This will be no faster/slower than chained method calls.

    If you do need to nest blocks in side of blocks, then do so with full indention:

    paths = [paths collect: ^(id path) {
        ...
        [someArray select:^(id path) {
            ...
        }];
    }];
    

    Just like nested if statements or the like. When it gets too complex, refactor it into functions or methods, as needed.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 263k
  • Answers 263k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Ah ha, we have found the answer: Thank you to… May 13, 2026 at 11:56 am
  • Editorial Team
    Editorial Team added an answer From all the documentation I've ever seen those three lines… May 13, 2026 at 11:56 am
  • Editorial Team
    Editorial Team added an answer To complete the former answers : An interface is a… May 13, 2026 at 11:56 am

Related Questions

Today I was experimenting with Objective-C's blocks so I thought I'd be clever and
I am experimenting with Intraweb right now, for a few small personal-use web apps
I've just started learning how to use pygame yesterday. I was read this one
I read an interesting DailyWTF post today, Out of All The Possible Answers... and
Today I was listening to the Hanselminutes show about .NET 3.5 SP1...What's inside ,

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.