When you use:
NSString *newText = sender.titleLabel.text;
you are just setting a pointer to the existing object at sender.titleLabel.text. You are telling the compiler that this new pointer points to an object of type NSString.
Note: the pointers newText and sender.titleLabel.txt now both point to the same object so changes made to the underlying object (such as changing the text) will be reflect when you access the object using either pointers.
Note 2: when you used:
NSString *newText = [[NSString alloc] initWithFormat:@"%@",sender.titleLabel.text];
You created an entirely new object (by using alloc) and then you init'd this new object with the string value of sender.titleLabel.text at the time the alloc operation was executed. Now newText and sender.titleLabel.text are two totally different NSString objects that are not related in anyway to each other and can be changed/managed/used/dealloc'd completely independently of each other.