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 919073
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T18:28:54+00:00 2026-05-15T18:28:54+00:00

I am writing the middleware for a cocoa application, and am debating over how

  • 0

I am writing the middleware for a cocoa application, and am debating over how exactly to design callbacks for many long running processes.

When the UI will call a function which executes for a long time, it needs to provide a delegate to allow at least:

  • Report of Success (with return value)
  • Report of Failure (with error value)
  • Report of Progress (completed, expected total)

I have tried a few techniques in the past, shown below

@interface MyClass {
}

//Callback Option1, delgate conforming to protocol
-(void) longRunningProcess2:(id<CallbackProtocol>) delegate;

//Callback Option2, provide a delegate and allow it to provide selectors to callback
-(void) longRunningProcess3:(id) delegate success:(SEL) s1 failure:(SEL) s2 progress:(SEL) s3
@end

For Options 1, the question is then how to phrase the delegate response. The first way I considered is (the function names are minimal for simplicity)

//have a generic callback protocol for every function
@protocol CallbackProtocolGeneric
-(void) success:(id) returnValue;
-(void) failure:(NSError*) error;
@optional
-(void) progress:(NSInteger) completed of:(NSInteger) total;
@end

//have a separate protocol for every function
@protocol CallbackProtocolWithObjectAForOperation1
-(void) objectA:(ObjectA*) objectA operation1SucceedWithValue:(ReturnObject*) value;
-(void) objectA:(ObjectA*) objectA operation1FailedWithError:(NSError*) error;
@optional
-(void) objectA:(ObjectA*) objectA operation1didProgress:(NSInteger) completed of:(NSInteger) total;
@end

In my experience,
Callback Option 1 using a generic protocol was difficult to use because if a class wanted to be a callback for multiple operations it could not distinguish which callback it was receiving.

Callback Option2 was cumbersome to use and felt un-natural to use. Plus if the protocol was extended it would require modifying every call.

Callback Option1 using a specific protocol for each process seems to be the most readable and scalable method, however I wonder if making a new protocol for every single function is too verbose (Say a given object has 10+ such ‘long operations’, then 10 different protocols).

What conclusions have other people come to when implementing such designs?

–edit:
In reply to Dave DeLong’s answer

I have three classes which have ‘long operations’, non of the operations in each class or between classes are really related. Some are network resource requests, others are long processing requests.

–edit:
A side note, I seem to have a problem where I cannot invoke run loop selectors for messages which have more than one argument. Is this a design limitation or is there a way around this?

For example I have a message such as
-(id) someMessage:(id) value1 otherData:(id) value2 moreData:(id) value3

The performSelector functions which queue runLoop’s do not support such selectors.

  • 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-15T18:28:55+00:00Added an answer on May 15, 2026 at 6:28 pm

    I’d chose longRunningProcess2 instead of longRunningProcess3 just because it’s easier to understand if you can see the method declarations on the protocol, as opposed to relying on documentation to work out what the callback method arguments are.

    I’d like to add that Apple uses blocks for callbacks in the API new to 10.6, which gives you another option if you aren’t supporting 10.5 or earlier.

    The blocks approach would look like this:

    -(void) longRunningProcessWithSuccessHandler:(void(^)(ReturnObject* value))successHandler
                                    errorHandler:(void(^)(NSError* error))errorHandler
                                 progressHandler:(void(^)(NSInteger completed, NSInteger total))progressHandler;
    {
        NSInteger totalItems = 10;
        NSInteger item = 0;
        for(item = 0; item < totalItems; ++item){
            [self processItem:item];
            progressHandler(item, totalItems);
        }
    
        BOOL wasSuccessful = ?;
        if(wasSuccessful){
            ReturnObject* value = ?;
            successHandler(value);
        } else {
            NSError* error = ?;
            errorHandler(error);
        }
    }
    

    And you would call the method like this:

    [SomeObj longRunningProcessWithSuccessHandler:^(ReturnObject* value) { [self showReturnObject:value]; }
                                     errorHandler:^(NSError* error){ [self presentError:error]; }
                                  progressHandler:^(NSInteger completed, NSInteger total) { [self updateProgressToPercent:(double)completed/total]; }];
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Writing a JSP page, what exactly does the <c:out> do? I've noticed that the
Writing my first Linq application, and I'm trying to find the best way to
Writing some test scripts in IronPython, I want to verify whether a window is
Writing the code for the user authentication portion of a web site (including account
Writing something like this using the loki library , typedef Functor<void> BitButtonPushHandler; throws a
When writing a switch statement, there appears to be two limitations on what you
When writing multi-threaded applications, one of the most common problems experienced are deadlocks. My
When writing multithreaded applications, one of the most common problems experienced is race conditions.
I writing a report in Visual Studio that takes a user input parameter and
When writing production-quality VC++ code, is the use of recursion acceptable? Why or why

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.