NSArray *retVal = [fetchResults retain]
should keep everything around for you. It doesn't make a copy, but I expect that's not really what you're trying to do. Your first attempt there should make a copy. They're all prone to leaking if you're not careful though (your second example leaks guaranteed). Are you sure you're not doing something else in the program that makes this part of the code fail?
Here are some options for doing a real copy if that's what you want:
NSArray *retVal = [fetchResults copy];
NSArray *retVal = [[NSArray alloc] initWithArray:fetchResults];
Both of those return retained arrays to you.