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