To see weak references in action, let’s add another array to the mix. What if we wanted an array of all assets – even ones that have not been assigned to a particular employee? We could add the assets to an array as they are created. Add a few lines of code to main.m:
#import <Foundation/Foundation.h> #import "Employee.h" #import "Asset.h" int main(int argc, const char * argv[]) { @autoreleasepool { // Create an array of Employee objects NSMutableArray *employees = [[NSMutableArray alloc] init]; for (int i = 0; i < 10; i++) { // Create an instance of Employee Employee *person = [[Employee alloc] init]; // Give the instance variables interesting values [person setWeightInKilos:90 + i]; [person setHeightInMeters:1.8 - i/10.0]; [person setEmployeeID:i]; // Put the employee in the employees array [employees addObject:person]; } NSMutableArray *allAssets = [[NSMutableArray alloc] init]; // Create 10 assets for (int i = 0; i < 10; i++) { // Create an asset Asset *asset = [[Asset alloc] init]; // Give it an interesting label NSString *currentLabel = [NSString stringWithFormat:@"Laptop %d", i]; [asset setLabel:currentLabel]; [asset setResaleValue:i * 17]; // Get a random number between 0 and 9 inclusive NSUInteger randomIndex = random() % [employees count]; // Find that employee Employee *randomEmployee = [employees objectAtIndex:randomIndex]; // Assign the asset to the employee [randomEmployee addAssetsObject:asset]; [allAssets addObject:asset]; } NSLog(@"Employees: %@", employees); NSLog(@"Giving up ownership of one employee"); [employees removeObjectAtIndex:5]; NSLog(@"allAssets: %@", allAssets); NSLog(@"Giving up ownership of arrays"); allAssets = nil; employees = nil; } sleep(100); return 0; }
Before you build and run your program, think about what you expect your output to look like. You’ll see the contents of the allAssets array – after Employee #5 has been deallocated. What will the status of Employee #5’s assets be at this point? These assets lose one owner (Employee #5), but they are still owned by allAssets, so they won’t be deallocated.
What about holder for the assets previously owned by Employee #5? When the object that a weak reference points to is deallocated, the pointer variable is zeroed, or set to nil. So Employee #5’s assets will not be deallocated, and their holder variables will be automatically set to nil.
Now build and run the program and check your output:
Employees: ( "<Employee 0: $0 in assets>", ... "<Employee 9: $136 in assets>" ) Giving up ownership of one employee deallocating <Employee 5: $136 in assets> allAssets: ( "<Laptop 0: $0, assigned to <Employee 3: $68 in assets>>", "<Laptop 1: $17, assigned to <Employee 6: $119 in assets>>", "<Laptop 2: $34, assigned to <Employee 7: $34 in assets>>", "<Laptop 3: $51 unassigned>", "<Laptop 4: $68, assigned to <Employee 3: $68 in assets>>", "<Laptop 5: $85 unassigned>", "<Laptop 6: $102, assigned to <Employee 6: $119 in assets>>", "<Laptop 7: $119, assigned to <Employee 2: $119 in assets>>", "<Laptop 8: $136, assigned to <Employee 9: $136 in assets>>", "<Laptop 9: $153, assigned to <Employee 1: $153 in assets>>" ) Giving up ownership of arrays deallocing <Laptop 3: $51 unassigned> ... deallocing <Laptop 8: $136 unassigned>