Bronze challenge issue


#1

So in the DetailViewController.m, i made the following changes in showAssetTypePicker method :-

[code]-(IBAction)showAssetTypePicker:(UIButton *)sender{
assetTypePicker= [[AssetTypePicker alloc] init];
[self.view endEditing:YES];
[assetTypePicker setItem:_item];
// [[assetTypePicker tableView] setDelegate:self];

if ([[UIDevice currentDevice] userInterfaceIdiom]==UIUserInterfaceIdiomPad ) {
    assetTypePickerPopover= [[UIPopoverController alloc] initWithContentViewController:assetTypePicker];
    NSLog(@"assetTypePickerPopover- %@",assetTypePickerPopover);
    [assetTypePickerPopover setDelegate:self];
    [assetTypePickerPopover presentPopoverFromRect:sender.bounds inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else{//..for iPhone
[self.navigationController pushViewController:assetTypePicker animated:YES];
}

}
[/code]

In AssetTypePicker.m also i added some code in -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath:-

[code]-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(@“Selecting a row in AssetTypePicker”);
UITableViewCell *cell= [tableView cellForRowAtIndexPath:indexPath];

[cell setAccessoryType:UITableViewCellAccessoryCheckmark];

NSArray *allAssets=[[BNRItemStore sharedStore] allAssetTypes];
NSManagedObject *assetType= [allAssets objectAtIndex:indexPath.row];

[item setAssetType:assetType];
if ([UIDevice currentDevice].userInterfaceIdiom== UIUserInterfaceIdiomPhone) {
    NSLog(@"popping off modal controller's view");
    [self.navigationController popViewControllerAnimated:YES];
}
else{//For the iPad
    NSLog(@"dismissing the AssetTypePickerPopover");
    [((DetailViewController *)self.navigationController)->assetTypePickerPopover dismissPopoverAnimated:YES];
    ((DetailViewController *)self.navigationController)->assetTypePickerPopover=nil;

}

}
[/code]
This is giving me a runtime error- Thread 1: EXC_BAD_ACCESS (code=2, address=(0X154)…No exception has been thrown and displayed in the console…Its bad memory access error…By the time the above message is sent to AssetTypePicker ,the objects- assetTypePicker and assetTypePickerPopover are already created in the topmost method… So why am i getting this??
What have i done wrong? :confused: :confused: I know this isn’t the cleanest way to write the functionality in DetailViewController.m (i’m using an ivar of one object directly in another object to send it dismissal message but lets just keep that aside and focus on the logical issue) Pls help…


#2

Putting aside (as you called it) the not so clean design pattern, it’s obvious why your app is crashing. You’ve made two incorrect assumptions.

Assumption #1 – In “DetailViewController.m” when you are showing the popover (when an iPad is detected), you are not using the navigationController. This means that DetailViewController is not part of the navigationController hierarchy, and DetailViewController has no navigationController as a parent controller (i.e. self.navigationController = nil in your instance of DetailViewController).

Later, when you attempt to tap the cell in AssetTypePicker.m and you check for the possibility of using an iPad, you refer to “self.navigationController” which does not exist.

Assumption #2 – Even if you had a valid self.navigationController, why would you think it is an instance of DetailViewController? Both DetailViewController and AssetTypePicker would be children of the navigationController. By type casting a UINavigationController to a DetailViewController you are telling the compiler “trust me when I tell you that self.navigationController is a type of a class called DetailViewController”. However in this case self.navigationController is nil, and even if it wasn’t, it is not an instance of DetailViewController, and it does not have an iVar called “assetTypePickerPopover”.

I suggest you either use delegation or a block as a (clean) callback to get notified whenever the table cell is tapped, in order to dismiss the popover.