When you call init on an object, the retain count goes to 1. You have two different setter attributes: one is "retain" for your UIButton, and the other is "copy" for your NSString. When you call
self.someButton = someUIButtonObject;
someUIButtonObject gets a retain message and so its retain count goes up to 1. In the case of your original code, calling release in dealloc will release one reference to someUIButtonObject, but it will still have a retain count of 1 and will thus be leaked.
The other case with your NSString has a different problem but still leaks memory. Here your call to [[NSString alloc] init] results in a new string object, and then calling
self.someString = someNSStringObject;
results in the creation of a brand new object which copies the content of someNSStringObject. In this case, someNSStringObject and the setter's copied object each have a retain count of one. Here, you leak the string you alloc init-ed because you no longer have a reference to it and it goes out of scope with a retain count of one.
A quick side note: I don't know what your actual code looks like, but don't forget that NSStrings are immutable (so just calling [[NSString alloc] init] is pretty useless) and UIButton needs a frame (try [[UIButton alloc] initWithFrame:(CGRect)frame];).
Basically you need to match each call to retain, copy, or alloc with a call to release (or autorelease). It is appropriate so use
self.someButton = [[[UIButton alloc] init] autorelease];
Which will release the object, though at some unknown time in the future. Don't use autorelease if your memory is very tight and you need memory ASAP. In that case you would do:
UIButton* tempButton = [[UIButton alloc] init];
self.someButton = tempButton;
[tempButton release];
which guarantees that you don't have large objects waiting around in your autorelease pool.
Also, always use the getters/setters to access these properties (self.someButton as opposed to someButton). That way you don't accidentally assign someButton to a new pointer and leak the old one.
When you create a button in IB, the XIB holds a reference to the button (+1 retain count). If you create an IBOutlet so you can access the button programmatically, you get another retain on the object, so if you have an IBOutlet to someButton, someButton has a retain count of 2 as soon as the XIB is loaded. You do not need to alloc the object, that is done automatically when the XIB is loaded into memory. Also, you are only responsible for releasing one reference to the button (your IBOutlet reference). In general, it is a good practice to release your reference as soon as you know you no longer need it. For example, if you know you need a button and have to do initial customization and nothing else, then you would probably do something like this:
-(void)viewDidLoad {
// Do some customization of someButton
[someButton release];
}
Otherwise you would probably release someButton in viewDidUnload since you know at that point you won't need the reference to the button anymore.