As a follow up to this question: Skip/ignore method in iOS, I'm trying to implement separate delegates for my UITableView in iOS7 and iOS8.
So, as a first step, in viewDidLoad of my MyTableViewController, I added the following code:
if ([[[UIDevice currentDevice] systemVersion] compare: #"8.0" options: NSNumericSearch] != NSOrderedAscending)
{
[self.tableView setDelegate: [[MyTVDelegate alloc] initWithIdentifier: myTVCellIdentifier]];
}
else
{
[self.tableView setDelegate: [[MyTVDelegate7 alloc] initWithIdentifier: myTVCellIdentifier]];
}
I'm adding an identifier, since I will have to apply this to multiple view controllers (or I may have just create a delegate class for each TV, I haven't figured that out yet).
I'm using CoreData, so my dataSource is an NSFetchedResultsController.
Then, I have the following for MyTVDelegate/myTVDelegate7:
#import "MyTVDelegate.h"
#implementation MyTVDelegate
- (instancetype)initWithIdentifier: (NSString *) identifier
{
if ([super init])
{
self.identifier = identifier;
}
return self;
}
#end
#implementation MyTVDelegate7
- (CGFloat)tableView: (UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *)indexPath
{
return 44;
}
- (CGFloat)tableView: (UITableView *)tableView estimatedHeightForRowAtIndexPath: (NSIndexPath *)indexPath
{
return UITableViewAutomaticDimension;
}
#end
If I run this, I'm getting the following runtime error in iOS7:
2015-01-18 10:42:51.894 -[__NSArrayI tableView:estimatedHeightForRowAtIndexPath:]: unrecognized selector sent to instance 0x7b9dd220
2015-01-18 10:42:57.731 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI tableView:estimatedHeightForRowAtIndexPath:]: unrecognized selector sent to instance 0x7b9dd220'
on iOS8, there is no crash.
The instance 0x7b9dd220 is an NSArray. My hunch is that it crashes, because the indexPath is invalid because the delegate and 'dataSource' are now separate?
I've tried moving the call to performFetch to either before or after setting the delegate, but I get the same error.
How do I fix this, should I for instance move all the NSFetchedResultsController code to the new delegate class as well?
self.tableView setDelegate: assigns a weak reference; if you don't hold your own reference to this object, it will get collected. This is why you're seeing the crash. The system has collected the memory that was assigned to your delegate, then reassigned the memory to an NSArray. Your table tries to call methods on the delegate and can't because NSArray does not respond to them.
Alongside the self.tableView property definition, define another property:
#property (strong) id<UITableViewDelegate> myTableViewDelegate;
Related
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
return [recieps count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [recieps objectAtIndex:indexPath.row];
return cell;
}
I want to display recipes list in Navigation table view but I am getting errors like unrecognized selector sent to instance 0x7f8c61709f80
"Unrecognized Selector" in iOS means you're attempting to call a method that the object you're asking doesn't understand.
You're saying [someObject doThisMethod], but someObject doesn't know what you're talking about.
Either the method doesn't exist for that object & needs to be added, or there's an issue with your storyboard connections or classes.
The error tells you what the problem is & where:
-[UIViewController tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x7fec31c38af0
This tells you that a tableView instance (at memory address 0x7fec31c38af0) received the message numberOfRowsInSection:, but it doesn't know what to do.
If you're using a custom class for your UITableView, make sure you've set it properly in your storyboard. Also make sure you've properly hooked up both UITableViewDelegate and UITableViewDataSource.
Since it doesn't recognize this required UITableViewDataSource protocol method, it's likely you forgot to add that or hook it up. Double-check your storyboard connections and that your UITableView class actually conforms to the UITableViewDataSource protocol.
Also, it's "recipe" ... you have misspelled it "recieps" in several places...
In your above code number of section method not called. Please add the below line of code
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
Note:
Then you are calling some method that is not exist in your controller.That's why you got the 'unrecognized selector' error message on console. Try to figure out the method and check again.
So I'm using the CoreAudioKit's CABTMIDICentralViewController to present a list of MIDI Bluetooth devices for the user to select. However, I want to be able to tell which device the user selected when they're done, but it doesn't seem Apple has added any way to do that.
So I'm trying to hack it by detecting when the user selects a row in the table:
DPBleMidiDeviceManager.h:
#import <CoreAudioKit/CoreAudioKit.h>
#interface DPBleMidiDeviceManager : CABTMIDICentralViewController
#end
DPBleMidiDeviceManager.m:
#import "DPBleMidiDeviceManager.h"
#implementation DPBleMidiDeviceManager
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"midi device selected %#", indexPath);
//either of these next lines crash, it makes no difference:
//[[tableView delegate] tableView:tableView didDeselectRowAtIndexPath:indexPath];
[super tableView:tableView didDeselectRowAtIndexPath:indexPath];
}
#end
The problem is, it's crashing on the last line saying there's no selector. Which is weird, because if I remove the super call, it doesn't crash, but it also doesn't correctly connect to the BLE device, like it would if I was not overriding that delegate call.
Is this just something Apple does so you can't access their tables? Why would they build a UI view like this and let you call it, but not give you any information about what the result was? Am I missing some standard way to do this?
EDIT: here's the details of the crash with the super call:
2015-10-29 15:14:37.039 [626:338267] midi device selected <NSIndexPath: 0x1473ae20> {length = 2, path = 0 - 3}
2015-10-29 15:14:37.039 [626:338267] -[DPBleMidiDeviceManager tableView:didDeselectRowAtIndexPath:]: unrecognized selector sent to instance 0x147f34e0
2015-10-29 15:14:37.040 [626:338267] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DPBleMidiDeviceManager tableView:didDeselectRowAtIndexPath:]: unrecognized selector sent to instance 0x147f34e0'
*** First throw call stack:
(0x2b3cdfef 0x3967dc8b 0x2b3d3409 0x2b3d11bf 0x2b300e78 0xaa165 0x2eb3956b 0x2ebe843b 0x2ea9da91 0x2ea1838f 0x2b393fed 0x2b3916ab 0x2b391ab3 0x2b2de201 0x2b2de013 0x32aab201 0x2ea82a59 0x88447 0x39c09aaf)
libc++abi.dylib: terminating with uncaught exception of type NSException
That's not how you call super. It should be
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"midi device selected %#", indexPath);
[super tableView:tableView didDeselectRowAtIndexPath:indexPath];
}
I'm trying to use a UISearchDisplayController to search with CLGeocode as the user types, for use with an MKMapView. My view controller has only two things in it - the UISearchBar associated with the UISearchDisplayController and the map view. I'm using a Storyboard.
Normally one would do this with an underlying table view and would declare a prototype cell there, but there seems to be no way of doing that here since I don't have the table view. So I created a subclass of UITableViewCell called SearchTableViewCell, with associated nib.
The nib contains one label, with this outlet connected:
#interface SearchTableViewCell : UITableViewCell
#property (unsafe_unretained, nonatomic) IBOutlet UILabel *textLabel;
#end
I load the nib in viewDidLoad:
[self.searchDisplayController.searchResultsTableView registerNib:[UINib nibWithNibName:#"SearchTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:#"CellIdentifier"];
I get the data from CLGeocoder like this:
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self.geocoder geocodeAddressString:searchString completionHandler:^(NSArray *placemarks, NSError *error) {
self.placemarks = placemarks;
[self.searchDisplayController.searchResultsTableView reloadData];
}];
return NO;
}
And my tableview code looks like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.placemarks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *kCellID = #"CellIdentifier";
SearchTableViewCell *cell = (SearchTableViewCell *)[tableView dequeueReusableCellWithIdentifier:kCellID forIndexPath:indexPath];
CLPlacemark *placemark = self.placemarks[indexPath.row];
NSString *addressString = CFBridgingRelease(CFBridgingRetain(ABCreateStringWithAddressDictionary(placemark.addressDictionary, NO)));
cell.textLabel.text = addressString;
return cell;
}
The search part is working - when I get to cellForRowAtIndexPath there is data in self.placemarks. However, the line that dequeues a new cell is failing with an exception the first time it's called:
'NSUnknownKeyException', reason: '[<NSObject 0x1a840d40> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key textLabel.'
My cell object is compliant for textLabel, but I'm wondering about that NSObject there in the error message - is the object being returned not a SearchTableViewCell? It is configured in IB to use the correct class. And why is the dequeue method checking for textLabel anyway? I'm pretty sure I've had custom table cells before that had no textLabel field.
Any suggestions on where I've gone wrong?
It turned out that somehow, I had two connections to textLabel - one proper one to the IBOutlet and another to File's Owner. That must have been how the NSObject was getting returned.
After fixing that, I was getting an assertion failure in -[NSLayoutConstraint constant]. Just on a whim I turned off AutoLayout in the nib, which didn't seem to need it and presto. it works now.
In my application I try to load contents from a url, store them in a mutable array and show them in a table view. But I can't get it working, because every time I run the app this error appears:
*** Terminating app due to uncaught exception 'NSRangeException',
reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(0x34dd088f 0x36d9e259 0x34d2823d 0x316e562f 0x315f09a9 0x313c0c5d 0x313c1b95 0x313c1ae7
0x313c16c3 0xa5cfb 0x33623ec7 0x35387a09 0x35390051 0x33622965 0xa4dc1 0x313a8e33
0x313cd629 0x31391d7d 0x314544dd 0x3139a55d 0x3139a579 0x3139a40b 0x3139a3e7 0x313a8015
0x313a1985 0x3136fc6b 0x3136f70f 0x3136f0e3 0x3439222b 0x34da4523 0x34da44c5 0x34da3313
0x34d264a5 0x34d2636d 0x313a0a13 0x3139de7d 0xa4745 0xa46dc)
terminate called throwing an exception
I create the array that should populate the table in my viewDidLoad with:
_videos = [[NSMutableArray alloc] init];
Then I connect to the url and parse through the received xml data. This works just like it should. When a certain tag is opened I create my video objects and after filling them with data I add those objects to my array with:
[_videos addObject:currentVideo];
This seems to work as well, because it returns the correct number of videos when
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _videos.count;
}
is called. But after this point the app crashes and I don't even reach the point where I try to populate my table view. The function looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Video *curVideo = [_videos objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"CustomCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.titleLabel.text = [curVideo title];
cell.descLabel.text = [curVideo desc];
return cell;
}
What am doing wrong?
Thanks in advance
I had the same error signature -[__NSArrayI objectAtIndex:]: index 4 beyond bounds [0 .. 1]' when attempting to present a modal Storyboard, table view with two (updated from five) static table cell sections. This error didn't come up until I removed three table cell sections I no longer needed in the view. After checking all my objectAtIndex references preceding the modal presentation at length for two days, I decided to look at the UITableViewController subclass code itself. I found this:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//#warning Potentially incomplete method implementation.
// Return the number of sections.
return 5;
}
Then the lightbulb went off. The index 4 being referred to related to my table view number of sections and the bound of [0 .. 1] referred to my current two table cell sections. Updating the return value to match the number of current table cell sections in the Storyboard table view resolved the issue.
Somewhere you are likely accessing _videos prior to initializing it. Most likely you'd doing it after init, but prior to loading the view. The fix for this kind of problem is to use accessors exclusively, and to lazy-initialize self.videos. This is one of many reasons never to access your ivars directly except in init and dealloc.
#interface ...
#property (nonatomic, readonly, strong) NSMutableArray *videos;
#end
#implementation ...
{
NSMutableArray *_videos; // Can't auto-synthesize. We override the only accessor.
}
- (NSMutableArray *)videos {
if (! _videos) {
_videos = [NSMutableArray new];
}
return _videos;
}
Now all references to self.videos will be initialized no matter when they happen.
You can also initialize videos correctly in init, which takes a little less code:
#interface ...
#property (nonatomic, readonly, strong) NSMutableArray *videos;
#end
#implementation ...
- (id)init {
self = [super init];
if (self) {
_videos = [NSMutableArray new];
}
return self;
}
I have passed dummy image name for images array like this,
arrImages = [NSArray arrayWithObjects:[UIImage imageNamed:#"some.png"]
The above line caused me error. So I changed #"some.png" with existed image like #"category.png".
This is worked for me. Make sure you are passing correct image name from your bundle.
i have looked through basically every single stack overflow question on this, but i cant find an answer. None of the answers seem to work.
I am writing an application that has a tableview in it, with a uitableview as a subview.
The uitableview is datasource and delegate connected to a class called xvalues, which is a subclass of uitableviewcontroller. i also have a class, where i load a custom uitableviewcell. This all doesn't cause any errors.
Here is my code for the uitableview, in xvalues:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
tableviewcell *cell = [[tableviewcell alloc]initWithFrame:CGRectZero];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
}
I removed some commented out methods such as can edit row at index path and commit editing style.
In cellforrowatindexpath, tableviewcell is my custom cell class.
From this, when i run my code, it loads up my uitableview, with 1 cell, with my custom cell.
However, now, if i click and drag, it works for dragging about an inch, and then suddenly crashes with the error:
2012-07-16 12:14:16.957 spreadsheet[68717:f803] -[__NSCFString tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x6894400
2012-07-16 12:14:16.960 spreadsheet[68717:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString tableView:cellForRowAtIndexPath:]: unrecognized selector sent to instance 0x6894400'
*** First throw call stack: blah blah blah
It also happens when i click on the row, but i think that is because of my did select row at index path method.
If anyone could help me it would be amazingly helpful.
Your table view controller is getting deallocated. Make sure you’re retaining your xvalues instance (or assigning it to a strong property on something, like your app delegate) wherever you’re creating it.