Reputation: 5373
My application is attempting to use a zombie instance of something, though i have no idea where the problem is. the exception consistently occurs when invoking (IBAction)addTag:sender
.
my stack trace is below:
2012-03-12 17:06:45.935 FavoriteTwitterSearches[3636:f803] -[__NSCFString addTag:]: unrecognized selector sent to instance 0x6a30d90
2012-03-12 17:06:45.943 FavoriteTwitterSearches[3636:f803] CRASH: -[__NSCFString addTag:]: unrecognized selector sent to instance 0x6a30d90
2012-03-12 17:06:45.947 FavoriteTwitterSearches[3636:f803] Stack Trace: (
0 CoreFoundation 0x013bc06e __exceptionPreprocess + 206
1 libobjc.A.dylib 0x0154dd0a objc_exception_throw + 44
2 CoreFoundation 0x013bdced -[NSObject doesNotRecognizeSelector:] + 253
3 CoreFoundation 0x01322f00 ___forwarding___ + 432
4 CoreFoundation 0x01322ce2 _CF_forwarding_prep_0 + 50
5 CoreFoundation 0x013bdec9 -[NSObject performSelector:withObject:withObject:] + 73
6 UIKit 0x000165c2 -[UIApplication sendAction:to:from:forEvent:] + 96
7 UIKit 0x0001655a -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
8 UIKit 0x000bbb76 -[UIControl sendAction:to:forEvent:] + 66
9 UIKit 0x000bc03f -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 503
10 UIKit 0x000bb2fe -[UIControl touchesEnded:withEvent:] + 549
11 UIKit 0x0003ba30 -[UIWindow _sendTouchesForEvent:] + 513
12 UIKit 0x0003bc56 -[UIWindow sendEvent:] + 273
13 UIKit 0x00022384 -[UIApplication sendEvent:] + 464
14 UIKit 0x00015aa9 _UIApplicationHandleEvent + 8196
15 GraphicsServices 0x012a6fa9 PurpleEventCallback + 1274
16 CoreFoundation 0x013901c5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
17 CoreFoundation 0x012f5022 __CFRunLoopDoSource1 + 146
18 CoreFoundation 0x012f390a __CFRunLoopRun + 2218
19 CoreFoundation 0x012f2db4 CFRunLoopRunSpecific + 212
20 CoreFoundation 0x012f2ccb CFRunLoopRunInMode + 123
21 GraphicsServices 0x012a5879 GSEventRunModal + 207
22 GraphicsServices 0x012a593e GSEventRun + 114
23 UIKit 0x00013a9b UIApplicationMain + 1175
24 FavoriteTwitterSearches 0x00001fab main + 187
25 FavoriteTwitterSearches 0x00001ee5 start + 53
26 ??? 0x00000001 0x0 + 1
)
objc[3636]: EXCEPTIONS: finishing handler
Support Files/Main.m:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
void uncaughtExceptionHandler(NSException *exception);
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal;
@try {
retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
@catch (NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
}
@finally {
[pool release];
}
return retVal;
}
Controller.m
#import "Controller.h"
@implementation Controller
- (id)init
{
if (self != nil)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dir = [paths objectAtIndex:0];
filePath = [[NSString alloc] initWithString:[dir stringByAppendingPathComponent:@"tagsIndex.plist"]];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:filePath] == NO)
{
tags = [[NSMutableDictionary alloc] init];
}
else
{
tags = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
}
buttons = [[NSMutableArray alloc] init];
infoButtons = [[NSMutableArray alloc] init];
}
return self;
}
- (void)awakeFromNib
{
for (NSString *title in tags)
[self addNewButtonWithTitle:title];
}
- (void)refreshList
{
for (UIButton *button in scrollView.subviews)
[button removeFromSuperview];
[infoButtons removeAllObjects];
float buttonOffset = BUTTON_SPACING;
for (UIButton *button in buttons)
{
CGRect buttonFrame = button.frame;
buttonFrame.origin.x = BUTTON_SPACING;
buttonFrame.origin.y = buttonOffset;
buttonFrame.size.width = scrollView.frame.size.width - BUTTON_SPACING - BUTTON_HEIGHT;
buttonFrame.size.height = BUTTON_HEIGHT;
button.frame = buttonFrame;
UIButton *infobutton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[infoButtons addObject:infobutton];
buttonFrame = infobutton.frame;
buttonFrame.origin.x = scrollView.frame.size.width - BUTTON_SPACING - SCROLLBAR_WIDTH;
buttonFrame.origin.y = buttonOffset;
infobutton.frame = buttonFrame;
[infobutton
addTarget:self action:@selector(infoButtonTouched:)
forControlEvents:UIControlEventTouchUpInside];
[scrollView addSubview:infobutton];
buttonOffset += BUTTON_HEIGHT + BUTTON_SPACING;
}
}
- (void)infoButtonTouched:sender
{
int index = [infoButtons indexOfObject:sender];
NSString *key = [[buttons objectAtIndex:index] titleLabel].text;
tagField.text = key;
NSString *value = [tags valueForKey:key];
queryField.text = value;
}
- (IBAction)addTag:sender
{
[tagField resignFirstResponder];
[queryField resignFirstResponder];
NSString *key = tagField.text;
NSString *value = queryField.text;
if (value.length == 0 || key.length == 0) return;
if ([tags valueForKey:key] == nil)
[self addNewButtonWithTitle:key];
[tags setValue:value forKey:key];
tagField.text = nil;
queryField.text = nil;
[tags writeToFile:filePath atomically:NO];
}
- (IBAction)clearTags:sender
{
[tags removeAllObjects];
[tags writeToFile:filePath atomically:NO];
[buttons removeAllObjects];
[self refreshList];
}
- (void)addNewButtonWithTitle:(NSString *)title
{
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:title forState:UIControlStateNormal];
[button
addTarget:self action:@selector(buttonTouched:)
forControlEvents:UIControlEventTouchUpInside];
[buttons addObject:button];
[buttons sortUsingSelector:@selector(compareButtonTitles:)];
[self refreshList];
CGSize contentSize = CGSizeMake(
scrollView.frame.size.width,
buttons.count * (BUTTON_HEIGHT + BUTTON_SPACING) + BUTTON_SPACING);
[scrollView setContentSize:contentSize];
}
- (void)buttonTouched:sender
{
NSString *key = [sender titleLabel].text;
NSString *search = [[tags valueForKey:key]
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *urlString = [NSString stringWithFormat:
@"http://search.twitter.com/search?q=%@", search];
NSURL *url = [NSURL URLWithString:urlString];
[[UIApplication sharedApplication] openURL:url];
}
- (void)dealloc
{
[filePath release];
[tags release];
[infoButtons release];
[buttons release];
[super dealloc];
}
@end
@implementation UIButton (sorting)
- (NSComparisonResult)compareButtonTitles:(UIButton *)button
{
return [self.titleLabel.text caseInsensitiveCompare:button.titleLabel.text];
}
@end
Upvotes: 3
Views: 263
Reputation: 237110
It sounds like most likely a Controller object is getting deallocated prematurely. It's not possible from the code you've posted to tell where it's happening, but you should be able to track it down with Instruments (zombies and malloc stack logging in particular). Or, if Controller isn't used in a lot of places†, it might be quicker just to look there and see if you're mistakenly autoreleasing it.
†For an object called something like "Controller", I wouldn't bet on it, but it's worth mentioning and being able to easily track the life cycle of objects is a great incentive to reduce coupling in your program designs.
Upvotes: 1
Reputation: 130162
[__NSCFString addTag:]: unrecognized selector sent to instance
says thay you are calling method addTag:
on an instance of type NSString
.
Check to what object and how is your IBAction connected in your xib. If everything is okey, try to clean your project, reset your simulator, and then try it again.
EDIT: please, add a NSLog
into your dealloc
to check if your controller has not been deallocated.
Upvotes: 2