As pointed in this answer string literals are immutable string objects and get their address in compile-time - so you don't need to create multiple instances of the same literal string during run-time.
NSString *myString = @"Hello";
So here we just assign myString to the pointer to string literal.
NSString *myString = [NSString stringWithString:@"Hello"];
The second line creates object using convenience constructor, but as we're dealing with immutable objects here it results to the same pointer value to string literal - so you get the same result as in 1st variant (although probably performing some extra methods calls).
So it seems that variants you mentioned do the same, but 2nd one may also perform some extra calls.
Small sample illustrating what happens:
NSString* tString = @"lala";
NSString* tString2 = @"lala";
NSString* tString3 = [NSString stringWithString:@"lala"];
NSString* tString4 = [NSString stringWithFormat:@"%@", @"lala"];
NSLog(@"%p %d", tString, [tString retainCount]);
NSLog(@"%p %d", tString2, [tString2 retainCount]);
NSLog(@"%p %d", tString3, [tString3 retainCount]);
NSLog(@"%p %d", tString4, [tString4 retainCount]);
Output:
0xd0418 2147483647
0xd0418 2147483647
0xd0418 2147483647
0x50280e0 1