2012-03-12 56 views
3

我的应用程序试图使用僵尸实例的东西,但我不知道问题出在哪里。调用(IBAction)addTag:sender时一致发生异常。
我的堆栈跟踪低于:目标c中的内存问题

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 

支持文件/ 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 
+2

为光滑的“主”实施+1 ... – Tim 2012-03-12 22:41:33

+1

不知何故,当按钮仍然活着并且在屏幕上时,您的“控制器”正在被解除分配。 – 2012-03-12 22:42:09

回答

1

听起来很可能是一个Controller对象过早地被释放。从你发布的代码中不可能知道它发生了什么,但是你应该能够使用Instruments(尤其是僵尸和malloc堆栈日志记录)来追踪它。或者,如果控制器没有在很多地方使用,那么只需看一看,看看你是否错误地将它自动释放。

†对于名为“控制器”的对象,我不打赌,但值得一提的是,能够轻松跟踪对象的生命周期对于减少程序设计中的耦合。

+0

Controller对象直接在主.xib上使用,并且在代码中没有其他直接引用。我将如何去确保它保持分配状态,还是我最好在合并对象和主视图控制器时打赌。 – 2012-03-13 01:19:04

2

[__NSCFString addTag:]: unrecognized selector sent to instance说大公你在实例调用方法addTag:类型NSString

检查你的xib中连接了什么对象,以及它是如何连接的。如果一切都是okey,请尝试清理您的项目,重置您的模拟器,然后重试。

编辑:请将NSLog加入您的dealloc以检查您的控制器是否未被释放。

+1

手动调用它并没有关系,回溯显示这是来自用户点击控件。 – 2012-03-12 22:41:10

+0

当然你是对的。 – Sulthan 2012-03-12 22:42:53

+0

笔尖上的每件东西都看起来不错,清理过的项目,重新设置了模拟器,然后再次尝试。没有运气。 – 2012-03-13 02:03:08