Reputation: 1375
I can't, for the life of me, figure this out. The employeeList array of the appDelegate is updating, without having any code telling it to update. The update occurs between the lines:
[tabs chargeInterest:days];
and
[array addObject:tabs.detailItem];
line. Therefore, it would appear as though the update occurs in the chargeInterest method, which can be seen below. The goal would be to prevent appDelegate.employeeList to not change at all.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (alertView.tag == 1) {
if (buttonIndex == 1) {
NSString *password = [alertView textFieldAtIndex:0].text;
NSString *days = [alertView textFieldAtIndex:1].text;
if ([password isEqualToString:@"admin"]) {
NSMutableArray *array = [[NSMutableArray alloc] init];
ViewTab *tabs = [[ViewTab alloc] init];
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
for (int g = 0; g < [appDelegate.employeeList count]; g++) {
id h = [appDelegate.employeeList objectAtIndex:g];
[tabs createDetailItem];
[tabs setDetailItem:h];
[tabs chargeInterest:days];
[array addObject:tabs.detailItem];
}
// Below tells the user whether or not any interest was charged.
float totalBefore = 0.0;
for (int x = 0; x < [appDelegate.employeeList count]; x++) {
id r = [appDelegate.employeeList objectAtIndex:x];
float tab = [[r tabTotal] floatValue];
totalBefore += tab;
}
float totalAfter = 0.0;
for (int y = 0; y < [array count]; y++) {
id s = [array objectAtIndex:y];
float tab = [[s tabTotal] floatValue];
totalAfter += tab;
}
}
}
}
}
The two methods referenced from ViewTab Class
- (void)createDetailItem {
if (!self.detailItem) {
self.detailItem = [[Employee alloc] init];
}
}
- (void)chargeInterest:(NSString *)daysOld {
NSDate *now = [[NSDate alloc] init];
NSNumber *numSeconds = [NSNumber numberWithDouble:[now timeIntervalSinceReferenceDate]];
int currentSeconds = [numSeconds intValue];
int days = [daysOld intValue];
int secondsOld = days * 86400;
NSMutableArray *arr = [[NSMutableArray alloc] init];
float newTotal;
for (int a = 0; a < [self.detailItem.tab count]; a++) {
id b = [self.detailItem.tab objectAtIndex:a];
NSNumber *numSecsSince = [NSNumber numberWithDouble:[[b dateAdded] timeIntervalSinceReferenceDate]];
int secondsSince = [numSecsSince intValue];
int secondsBetween = currentSeconds - secondsSince;
if (secondsBetween > secondsOld) {
float price = [[b price] floatValue];
price *= 2;
[b setPrice:[NSNumber numberWithFloat:price]];
}
newTotal += [[b price] floatValue];
[arr addObject:b];
}
[self.detailItem setTab:arr];
NSNumber *num = [NSNumber numberWithFloat:newTotal];
[self.detailItem setTabTotal:num];
}
Upvotes: 0
Views: 44
Reputation: 534977
Consider these four lines of your code:
id h = [appDelegate.employeeList objectAtIndex:g];
[tabs createDetailItem];
[tabs setDetailItem:h];
[tabs chargeInterest:days];
Without even bothering to read chargeInterest
, I just want to get you to stipulate that this code certainly could cause a change within appDelegate.employeeList
. Why? Because h
is now shared between appDelegate.employeeList
and tabs
; you obtained a reference to h
by fetching an element of appDelegate.employeeList
, and you handed that reference to tabs
, which is therefore free to mutate h
(assuming that h
is of a type that is not completely immutable, such as NSString).
This is true any time two objects share a reference to the same third object. Either one of them can change that third object. References to objects in Objective-C are just pointers. So an object is not immune from being mutated merely because you have a reference to it, because someone else might also have a reference to it and mutate it.
If you don't want that to happen, then either you need to design an immutable object type (like NSString and so on) or else you need to copy the object before you go sharing it with someone else.
Upvotes: 1