Return multiple objects from a method


With the new literals in Xcode 4.4 (and presumably a version for iOS) returning multiple objects from a method becomes almost as easy as in Python. The last example below returns a tuple with very little ceremony in a manner reasonably close to Python. The only thing missing is automatic unboxing into multiple variables.

Below are seven methods running from the oldest form supported bt K&R “C” so true tuple returning supported by the latest LLVM 4.x compiler and Xcode 4.4.

The oldest method is to return the results via reference variables
This method violates Apple coding guidelines that returning results via method references is to be avoided whenever possible.

@implementation ViaReferenceVars

- (void)userName:(NSString **)userName userID:(NSString **)userID {

    // …

    *userName = computedUserName;

    *userID   = computedUserID;

}

- (void)test {

    NSString *userName;

    NSString *userID;

    [self userName:&userName userID:&userID];

    NSLog(@”ViaReferenceVars – name: ‘%@’, userID: ‘%@’”, userName, userID);

}

@end

Return via ivar properties
Pollutes ivar space

@interface ViaIVars ()

@property NSString *userNameProperty;

@property NSString *userIDProperty;

@end

@implementation ViaIVars

- (void)userNameUserID {

    // …

    self.userNameProperty = computedUserName;

    self.userIDProperty   = computedUserID;

}

- (void)test {

    [self userNameUserID];

    NSLog(@”ViaIVars – name: ‘%@’, userID: ‘%@’”, self.userNameProperty, self.userIDProperty);

}

@end

Return via class

@interface DataModel : NSObject

@property NSString *userName;

@property NSString *userID;

@end

@implementation DataModel

@end

@implementation ViaClass

- (DataModel *)userNameUserID {

    // …

    DataModel *nameAndID = [DataModel new];

    nameAndID.userName = computedUserName;

    nameAndID.userID   = computedUserID;

    return nameAndID;

}

- (void)test {

    DataModel *dataModel = [self userNameUserID];

    NSLog(@”ViaClass – name: ‘%@’, userID: ‘%@’”, dataModel.userName, dataModel.userID);

}

@end

Return via class factory

@interface DataModel1 : NSObject

@property NSString *userName;

@property NSString *userID;

+ (id)userName:(NSString *)userName userID:(NSString *)userID;

@end

@implementation DataModel1

+ (id)userName:(NSString *)userName userID:(NSString *)userID {

    DataModel1 *nameAndID = [DataModel1 new];

    nameAndID.userName = userName;

    nameAndID.userID   = userID;

    return nameAndID;

}

@end

@implementation ViaClassFactory

- (DataModel1 *)userNameUserID {

    // …

    return [DataModel1 userName:computedUserName userID:computedUserID];

}

- (void)test {

    DataModel1 *dataModel = [self userNameUserID];

    NSLog(@”ViaClassFactory – name: ‘%@’, userID: ‘%@’”, dataModel.userName, dataModel.userID);

}

@end

Return via dictionary
Meets Apple coding guidelines, messy

@implementation ViaDictionary

- (NSDictionary *)userNameUserID {

// …

    return [NSDictionary dictionaryWithObjectsAndKeys:computedUserName, @"name", computedUserID, @"id", nil];

}

- (void)test {

    NSDictionary *nameAndID = [self userNameUserID];

    NSLog(@”ViaDictionary – name: ‘%@’, userID: ‘%@’”, [nameAndID objectForKey:@"name"], [nameAndID objectForKey:@"id"]);

}

@end

Return via dictionary literals
Meets Apple coding guidelines, neat, concise

@implementation ViaDictionaryLiterals

- (NSDictionary *)userNameUserID {

    // …

    return @{@”name”:computedUserName, @”id”:computedUserID};

}

- (void)test {

    NSDictionary *nameAndID = [self userNameUserID];

    NSLog(@”ViaDictionaryLiterals – name: ‘%@’, userID: ‘%@’”, nameAndID[@"name"], nameAndID[@"id"]);

}

@end

Return via array (new style)
Closest to python style

@implementation ViaArrayLiterals

- (NSArray *)userNameUserID {

    // …

    return @[computedUserName, computedUserID];

}

- (void)test {

    NSArray *nameAndID = [self userNameUserID];

    NSLog(@”ViaArrayLiterals – name: ‘%@’, userID: ‘%@’”, nameAndID[0], nameAndID[1]);

}

@end

About zaph

Long term Mac/iOS & Cocoa developer.
This entry was posted in Uncategorized. Bookmark the permalink.

3 Responses to Return multiple objects from a method

  1. Deandra says:

    Your post captures the issue preeftcly!

  2. Hi, thanks for sharing. I’m wondering if it’s OK to copy some of the text in my site?

Leave a Reply