Error: unrecognized selector sent to instance - objective-c

I have a custom object, Spaces:
#import "Spaces.h"
#implementation Spaces
#synthesize spaceName;
#synthesize spaceUsers;
#synthesize spaceIcon;
#synthesize spaceID;
#synthesize imageURLString;
- (void)dealloc
{
[spaceName release];
[spaceUsers release];
[spaceIcon release];
[imageURLString release];
[super dealloc];
}
#end
My root view controller implements a cellForRowAtIndexPath: and grabs from an NSArray of Spaces:
[[cell spaceName] setText:aSpace.spaceName];
[[cell spaceChatType] setText:#"People"];
[[cell spaceActiveUsers] setText:aSpace.spaceUsers];
This works fine and I can click to go into the detail view and back to the list, but after maybe 5-6 clicks back and forth between the table view and detail view, I get an error at [[cell spaceName] setText:aSpace.spaceName]; which is
'-[__NSCFSet spaceName]: unrecognized selector sent to instance 0x6047b90'"
Please help! Any insight will be very appreciated!
UPDATE:
I'm still getting the same error but I've narrowed it down to the this:
-I'm creating a detail view controller on didSelectRowAtIndexPath...
-The detail view is being pushed to the viewcontroller and displays fine, I have a back button added as well.
-The detail view loads information and refreshes on a timer
-Pressing the back button goes back to the table list view
This is the problem my detail view is not being released from memory so the more I go back and forth between the views the more timers were going off simultaneously. I added a check to viewWillDisappear that stops the timer by setting a bool value.
I noticed that the detail view is not unloading...
From the RootViewController:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//no longer on initial view
isinit = NO;
//hide keyboard
[spacesSearch resignFirstResponder];
if (spaces != nil && spaces.count > 0)
{
//set back button reference
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Spaces" style:UIBarButtonItemStylePlain target:self action:#selector(returnSpacesList:)];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
DetailViewController *details = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
//Grab Data from selected Space object and pass to DetailViewController
Spaces *aSpace = nil;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
if ([self.filteredListContent count] == 0)
{
//self.lastSearchText
NSLog(#"Create new space code!");
}
else
{
aSpace = [self.filteredListContent objectAtIndex:indexPath.row];
}
}
else
{
aSpace = [spaces objectAtIndex:[indexPath row]];
}
//set title and display
self.navigationController.title = [NSString stringWithFormat:#"/%#/",aSpace.spaceName];
//pass data
[details passedValue:aSpace.spaceID :aSpace.spaceName];
[self.navigationController pushViewController:details animated:YES];
[aSpace release];
[details release];
}
}
How can I force the detail view to be released from memory?
Thank you

It sounds like [cell spaceName] has been autoReleased. I cannot see how you have defined that, but take a look at that part of your code.
If you need more help, you need to provide more code.

Perhaps your aSpace = [spaces objectAtIndex:[indexPath row]];
is not returning a Space object. Perhaps before you try and use it you test to make sure with something like if ([aSpace class] == [Spaces class])

Related

UITableView is null after first data load, reloadData does not work

I have a custom UIView with a UITableView in it. I connect the delegate and dataSource via interface builder, it looks like this: http://postimg.org/image/nj9elaj4h/ (may not upload images yet :( )
When I load the view, the data is displayed as it should be. But when I try to call reloadData, nothing happens. I checked if the uitableview is set, but it is NULL. But as soon as I drag the tableView and it reloads it views, the new data is presented. Anyone got an idea why reloadData does not work?
.h looks like this:
#interface NextTitleView : UIView<UITableViewDataSource,UITableViewDelegate,SociusClientDelegate,UIActionSheetDelegate,Ne xtTitleCustomCellDelegate>
{
NexTitleCustomCell* _cellInFocus;
}
#property(nonatomic,retain)IBOutlet UITableView* _tableViewNextTitle;
#end
thanks for your help :D
EDIT: Added .m file
#implementation NextTitleView
#synthesize _tableViewNextTitle;
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(id)init
{
if(self)
{
[SharedSingeltons sharedInstance]._client.delegateCustomClient = self;
_tableViewNextTitle = [[UITableView alloc]init];
}
return self;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if(section == 0)
return #"Now playing";
if(section == 1)
return #"Comming Next";
else
return #"";
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == 0)
return 1;
if (section == 1)
return [[SharedSingeltons sharedInstance]._client._musicList count];
else
return 0;
}
-(NexTitleCustomCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NexTitleCustomCell* cell = [[NexTitleCustomCell alloc]init];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"NextTitleCustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
MusicItem* item = [[SharedSingeltons sharedInstance]._client._musicList
objectAtIndex:indexPath.row];
cell.delegate = self;
cell._labelSongTitle.text = item._songTitle;
cell._labelSongTitle.textColor = [UIColor blackColor];
cell._labelSubtitle.text = item._artist;
cell._identifier = item._songIdentifier;
cell._labelRating.text = item._rating.stringValue;
return cell;
}
-(void)clientDidReceiveMusicList:(SociusClient *)sender list:(NSMutableArray *)array
{
for(MusicItem* item in [SharedSingeltons sharedInstance]._client._musicList)
{
NSLog(#"rating:%#",item._rating);
}
NSLog(#"TAbleVIEW:%#",_tableViewNextTitle);
[self._tableViewNextTitle reloadData];
}
-(void)didPressActionButton:(NexTitleCustomCell *)sender
{
NSLog(#"Show alert view");
_cellInFocus = sender;
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Vote Up", #"Like",#"Remember", nil];
[popupQuery showInView:self];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 0)
{
NSLog(#"Vote up");
[self sendUpdateVoteForSong];
}
}
-(void)sendUpdateVoteForSong
{
NSMutableDictionary* dict = [[NSMutableDictionary alloc]init];
[dict setObject:_cellInFocus._identifier forKey:#"Vote"];
NSLog(#"Identifier:%#",_cellInFocus._identifier);
[[SharedSingeltons sharedInstance]._client sendObject:dict error:nil];
}
#end
I would say you are calling reload data too soon, probably in initWithNibName, you should be calling it in viewDidLoad.
I just set up a uiviewcontroller to handle the view. Now it works fine.
I think that UIActionSheet led to the problem,you can try to reloadData twice.
I noticed you are New-ing your Table view, but it's an Outlet... You don't need to alloc init your table view, if it's an IBOutlet. So either get rid of the IBOutlet, and just declare it as a property (but then you need to make sure you lay out your Table view programmatically), or keep the IBOutlet, and get rid of the code to alloc init it. Currently also your datasource and delegate are set from IB, so if you alloc init your table view, those won't be set anymore...
The tableview outlet should NOT be nil.
Can you put a breakpoint in awakeFromNib, and see if the TableView outlet is NIL there?
Are you loading the View Class that contains the table view by using its NIB file properly?
If you just embed the View class in the storyboard, it will not load the NIB automatically. I usually use a View container in that case, then load the NIB programmatically, and embed the loaded view in the view container programmatically.
NSArray *arrayXibObjects = [[NSBundle bundleWithIdentifier:#"net.mycompany.myappid"] loadNibNamed:#"myNibName" owner:nil options:nil];
for (id object in arrayXibObjects) {
if ([object isKindOfClass:myNibsClass]) {
return object; // this is your class loaded from NIB
}
}
This code can be placed in a utility method, to make it accessible with 1 line of code.
The returned Class is going to have the IBOutlets connected from the NIB to it's respective Class.
Now check in the debugger:
po [loadedClassFromNib tableView] // should not be NIL
Then embed the loaded NIB in the container like this: (or use constraints)
[self.viewContainer addSubview: classLoadedFromNib];
classLoadedFromNib.frame = self.viewContainer.frame;

MGSplitViewController as Modal not working correctly

I am trying to use an MGSplitViewController, but rather than having it set as the rootViewController, I want it to show modally. This is the code I am using so far
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath: (NSIndexPath *)indexPath
{
if(splitViewController == nil)
{
self.splitViewController = [[MGSplitViewController alloc] init];
self.rootViewController = [[RootViewController alloc] init];
self.detailViewController = [[DetailViewController alloc] init];
}
[splitViewController setViewControllers:[NSArray arrayWithObjects:rootViewController, detailViewController, nil]];
if (NO) { // whether to allow dragging the divider to move the split.
splitViewController.splitWidth = 15.0; // make it wide enough to actually drag!
splitViewController.allowsDraggingDivider = YES;
}
splitViewController.delegate = detailViewController;
[rootViewController performSelector:#selector(selectFirstRow) withObject:nil afterDelay:0];
[detailViewController performSelector:#selector(configureView) withObject:nil afterDelay:0];
[self presentViewController:splitViewController animated:YES completion:nil];
}
This works almost fine, but the buttons in the detailViewController do not work. They do nothing. Also, when I click a button in the left panel, the text doesn't change in the detailViewController as it does in the same project.
Am I missing something?
I'm also working with MGSplitViewController, but it sounds to me like you need to set up some communication between your master and detail views. If you look at the demo project, you can see they use delegates to that effect.

Memory Management Advice

In my root view, I have a tableview with three rows. When I click either row, it will present a new view and then I can press the back button that is automatically created by my nav controller. My problem arises when I try to click a row that has already been chosen before. I get an EXC BAD ACCESS error message. I think this is all the code that is neccessary:
- (void)dealloc
{
self.rowChosenArray = nil;
self.rootChoicesArray = nil;
self.customImage = nil;
self.rootTableView = nil;
[super dealloc];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.rootChoicesArray = [[[NSMutableArray alloc] initWithObjects:#"",#"See Today's Deals!", #"My Purchased Deals", #"Personal Settings", nil] autorelease];
self.rowChosenArray = [[[NSMutableArray alloc] initWithObjects:#"", nil] autorelease];
DealsViewController *dealsViewController = [[DealsViewController alloc] initWithNibName:#"DealsViewController" bundle:nil];
[self.rowChosenArray addObject:dealsViewController];
[dealsViewController release];
PurchasedDealsViewController *purchasedDealsViewController = [[PurchasedDealsViewController alloc] initWithNibName:#"PurchasedDealsViewController" bundle:nil];
[self.rowChosenArray addObject:purchasedDealsViewController];
[purchasedDealsViewController release];
SettingsViewController *settingsViewController = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
[self.rowChosenArray addObject:settingsViewController];
[settingsViewController release];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController *targetViewController = [rowChosenArray objectAtIndex: indexPath.row];
[[self navigationController] pushViewController:targetViewController animated:YES];
[targetViewController release];
}
I am still unfamiliar where/when to release/set objects to nil (all four of my objects have the retain property in the header file.
Thank you in advance for the help, let me know if there is anything else you may need.
Before you add an element into an array, you alloc it, but release it once it is added - so there is no leak;
You never need to release the elements in the array, because they will be released at the time when you release the array itself.
You are over-releasing targetViewController in tableView:didSelectRowAtIndexPath:. You get a non-owning reference through objectAtIndex: (which means that you are not responsible for that reference) and may not release that reference. So just remove [targetViewController release]; and everything's fine.
The rule is like this: you may only release a reference if you either retained it or got it through a method whose name:
is or starts with alloc, copy or mutableCopy
starts with new
also you have some leaks here, if you retain in viewDidLoad you should release/nil in viewDidUnload and in dealloc

Online Tutorial Not Working, Request for Member not in a structure or Union?

I'm new to iOS Development, so I've been following a bunch of tutorials online on how to make drill-down applications. I've run into this problem on two builds and I can't seem to get over it. I'm creating a tab bar application. In my app delegate, I define a tab bar, navigation controller, view controller, and an NSDictionary for my .plist. Problem is, when I get to my ViewController.m's file and start telling it to use the navigation controller i created, I get the error "Request for member is something not a structure or union."
I've tried this twice, quadrupled checked the code, and I still don't get it. Any help would be greatly appreciated :)
Below is the tableView method from my ViewController.m file.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the dictionary of the selected data source.
NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
//Get the children of the present item.
NSArray *Children = [dictionary objectForKey:#"Children"];
if([Children count] == 0) {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:[NSBundle mainBundle]];
[self.indNavControl pushViewController:dvController animated:YES];
[dvController release];
}
else {
//Prepare to tableview.
IndustriesViewController *indViewControl = [[IndustriesViewController alloc] initWithNibName:#"IndustryView" bundle:[NSBundle mainBundle]];
//Increment the Current View
indViewControl.CurrentLevel += 1;
//Set the title;
indViewControl.CurrentTitle = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.indNavControl pushViewController:indViewControl animated:YES];
indViewControl.tableDataSource = Children;
[indViewControl release];
}
}
did you synthesize indNavControl?

Objective-C TableView Select Item Troubles

I'm having trouble having my app respond when an Item is selected in the table view. I'm running everything from my app delegate (the table functions that is like dataSource and TitleForHeaderAtSection etc) which are all being called fine. However it is not calling my selection method when I tap on a item in the list. I even put a NSLog to see just in case.
Here's my code: (its quite long and extensive and I know theres crap in there that doesn't need to be there but I put all of it just in case you needed it...)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Selected Row.", #"");
//Get the selected country
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSDictionary *dictionary = [data objectAtIndex:indexPath.section];
//NSArray *array = [dictionary objectForKey:#"My Wishlists"];
//NSString *selectedWishlist = [array objectAtIndex:indexPath.row];
//Initialize the detail view controller and display it.
WishlistDetailView *dvController = [[WishlistDetailView alloc] initWithNibName:#"WishlistDetailView" bundle:[NSBundle mainBundle]];
dvController.selectedWishlistId = [wishlistids objectAtIndex:indexPath.row];
NSLog(#"Selected row with wishlist id: %#", dvController.selectedWishlistId);
[[self navController] pushViewController:dvController animated:YES];
[dvController release];
dvController = nil;
}
The code compiles with NO errors.
Thanks for your persistant help!!
Christian Stewart
(by the way both of the selection allowed checkboxes are checked in Interface builder.)
tableView:didSelectRowAtIndexPath: is a UITableViewDelegate method. Is you controller the delegate of the table view?