This explanation from IBM is helpful to me:
For example, we can think of Car as a whole entity and Car Wheel as part of the overall Car. The wheel can be created weeks ahead of time, and it can sit in a warehouse before being placed on a car during assembly. In this example, the Wheel class's instance clearly lives independently of the Car class's instance. However, there are times when the part class's lifecycle is not independent from that of the whole class — this is called composition aggregation. Consider, for example, the relationship of a company to its departments. Both Company and Departments are modeled as classes, and a department cannot exist before a company exists. Here the Department class's instance is dependent upon the existence of the Company class's instance.
So to me, the creator/destroyer life cycle (new, release) for a composition goes inside an instance; an aggregation must have the option instead to addObject and the method simply save the object id as an attribute of itself. So in the above Client and Bank Account example, it's really up to the business to determine if an Account can exist even if the Client record is destroyed (orphaned accounts) If it is aggegator, you would have Client methods:
Class Client {
- (void) addToAccount:(BankAccount *)acc;
- (void) removeFromAccount:(BankAccount *)acc;
}
and the close account method would be part of the BankAccount object instance, since it can exist independently from the Client.
versus the composition method which requres the Client to exist, and if the Client ceases to exist, all the accounts belonging to that account owner are deleted. Therefore, you would ask the Client object to create you an account:
Class Client {
- (BankAccount *) openAccount;
- (BOOL) closeAccount:(BankAccount *)acc;
}