2012-03-12 12 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

滑らかな 'main'の実装では... – Tim

+1

ボタンがまだ生きていて画面上にある間に、どういうわけか、あなたの' Controller'がdeallocされています。 –

答えて

1

コントローラオブジェクトが途中で解放される可能性が高いと思われます。投稿したコードからはどこに起こったのかを伝えることはできませんが、Instruments(ゾンビやmallocスタックのロギング)を使って追跡できるはずです。または、Controllerが多くの場所で使用されていない場合は、そこを見て誤って自動リリースしているかどうかを確認するほうが簡単です。

†「コントローラ」のようなオブジェクトの場合、私はそれに賭けることはありませんが、オブジェクトのライフサイクルを簡単に追跡できることは、プログラム設計におけるカップリングを減らす大きなインセンティブです。

+0

Controllerオブジェクトは、メインの.xibで直接使用され、コード内に直接参照はありません。どのように私はこれが割り当てられたままになっているかを確認するか、または私はちょうどメインのビューコントローラとオブジェクトをマージするより良い賭けを持っていますか? –

2

[__NSCFString addTag:]: unrecognized selector sent to instanceは、インスタンス上でメソッドaddTag:を呼び出している持ち運びにくいと言いますタイプNSStringです。

あなたのIBActionはどのオブジェクトにどのように接続されているかを確認してください。すべてがokeyなら、あなたのプロジェクトをきれいにして、シミュレータをリセットしてから、もう一度試してみてください。

EDIT:コントローラが割り当て解除されていないかどうかを確認するには、deallocNSLogを追加してください。

+1

彼はそれを手動で呼んでも問題はありません。バックトレースは、これがユーザーがコントロールをタップしていることを示しています。 –

+0

あなたはもちろんです。 – Sulthan

+0

すべてのことがペン先できれいに見え、プロジェクトをきれいにし、シミュレータをリセットして、もう一度試しました。運がない。 –