2011-04-12 21 views
5

我收到以下錯誤消息,我不明白爲什麼它發生,因爲我沒有使用任何UIImageView。有時我會得到同樣的錯誤,但是它的CALayer?!?無法識別的選擇器發送到實例

值得一提的是,我有2個筆尖和2個控制器以及一個基本控制器,這個代碼位於哪裏。

編輯:

這是我的項目

MainViewController &其筆尖 的結構 - HomeViewController在筆尖

MainViewController - 風景&其筆尖 - HomeViewController-景觀筆尖

HomeViewControllerBase - no nib - 基類,其中所有o存在utlets和項目配置代碼。 - 以下兩個子類都使用插座。 - 出口連接到每個主要筆尖的控件。

HomeViewController - 從HomeViewControllerBase

繼承

HomeViewController - 風景 - 從HomeViewControllerBase

繼承

那麼什麼情況是,子類試圖dealloc的基類(其中包含所有網點的話) 。我已經這樣設計,以避免不同方向viewcontrollers中的代碼重複。

@implementation MainViewController 
- (void)orientationChanged:(NSNotification *)notification 
{ 
    UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation; 

    if (UIDeviceOrientationIsLandscape(deviceOrientation) && !isShowingLandscapeView) 
    { 
     [self presentModalViewController:self.landscapeViewController 
           animated:YES]; 

     isShowingLandscapeView = YES; 
    } 
    else if (UIDeviceOrientationIsPortrait(deviceOrientation) && isShowingLandscapeView) 
    { 
     [self dismissModalViewControllerAnimated:YES]; 
     isShowingLandscapeView = NO; 
    } 
} 

- (id)init 
{ 
    self = [super initWithNibName:@"MainViewController" bundle:nil]; 

    if (self) 
    { 
     isShowingLandscapeView = NO; 
     self.landscapeViewController = [[[MainViewController_Landscape alloc] 
              initWithNibName:@"MainViewController-Landscape" bundle:nil] autorelease]; 

     [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
     [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(orientationChanged:) 
                name:UIDeviceOrientationDidChangeNotification 
                object:nil]; 
    } 

    return self; 
} 
@end 

@implementation HomeViewControllerBase 

    - (void)bestSellItemTapped:(id)sender 
    { 
     NSLog(@"best sell item tapped"); 
    } 

    - (void)configureBestSellItems 
    { 
     [self startRetrievingRegions]; 

     // load all the images from our bundle and add them to the scroll view 
     // NSUInteger i; 
     for (int i = 0; i <= 150; i++) 
     { 

      UILabel *itemTitle = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 100, 50)]; 
      itemTitle.text = @"Majorca"; 

      UILabel *itemPrice = [[UILabel alloc]initWithFrame:CGRectMake(0, 50, 100, 50)]; 
      itemPrice.text = @"£249"; 

      NSString *imageName = @"tempImage.jpg"; 
      UIImage *image = [UIImage imageNamed:imageName]; 


      UIButton *mainButton = [[[UIButton alloc]init] autorelease]; 

      [mainButton addTarget:self action:@selector(bestSellItemTapped:) forControlEvents:UIControlEventTouchUpInside]; 
      [mainButton setBackgroundImage:image forState:UIControlStateNormal]; 



      // setup each frame to a default height and width, it will be properly placed when we call "updateScrollList" 
      CGRect rect = mainButton.frame; 
      rect.size.height = kScrollObjHeight; 
      rect.size.width = kScrollObjWidth; 

      mainButton.frame = rect; 
      mainButton.tag = i; 


      [mainButton addSubview:itemTitle]; [itemTitle release]; 
      [mainButton addSubview:itemPrice]; [itemPrice release]; 




      [self.bestSellScrollView addSubview:mainButton]; 


     } 

     [self layoutScrollImages]; // now place the photos in serial layout within the scrollview 
    } 


    // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
    - (void)viewDidLoad 
    { 
     [super viewDidLoad]; 
     [self configureBestSellItems]; 
    } 

    - (void)layoutScrollImages 
    { 
     UIButton *view = nil; 
     NSArray *subviews = [self.bestSellScrollView subviews]; 

     // reposition all image subviews in a horizontal serial fashion 
     CGFloat curXLoc = 0; 
     for (view in subviews) 
     { 
      if ([view isKindOfClass:[UIButton class]] && view.tag > 0) 
      { 
       CGRect frame = view.frame; 
       frame.origin = CGPointMake(curXLoc, 0); 
       view.frame = frame; 

       curXLoc += (kScrollObjWidth + kScrollObjPadding); 
      } 
     } 

     // set the content size so it can be scrollable 
     [self.bestSellScrollView setContentSize:CGSizeMake((150 * kScrollObjWidth), 
                  [self.bestSellScrollView bounds].size.height)]; 
    } 

@end 

@interface HomeViewController : HomeViewControllerBase 
@end 

@interface HomeViewController_Landscape : HomeViewControllerBase 
@end 

@implementation HomeViewController 

- (void)dealloc 
{ 
    [super dealloc]; //When I remove this it works 
} 

@end 

@implementation HomeViewController_Landscape 

- (void)dealloc 
{ 
    [super dealloc]; //When I remove this it works 
} 

@end 

-[UIImageView bestSellItemTapped:]: unrecognized selector sent to instance 0x681c2b0 2011-04-12 15:45:26.665 [21532:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIImageView bestSellItemTapped:]: unrecognized selector sent to instance 0x681c2b0' 
*** Call stack at first throw: ( 0 CoreFoundation      0x00dc85a9 __exceptionPreprocess + 185 1 libobjc.A.dylib     0x00f1c313 objc_exception_throw + 44 2 CoreFoundation     0x00dca0bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187 3 CoreFoundation      0x00d39966 ___forwarding___ + 966 4 CoreFoundation      0x00d39522 _CF_forwarding_prep_0 + 50 5 UIKit        0x0001a4fd -[UIApplication sendAction:to:from:forEvent:] + 119 6 UIKit        0x000aa799 -[UIControl sendAction:to:forEvent:] + 67 7 UIKit        0x000acc2b -[UIControl(Internal) 
_sendActionsForEvents:withEvent:] + 527  8 UIKit       0x000ab7d8 -[UIControl touchesEnded:withEvent:] + 458  9 UIKit        0x002ad4de 
_UIGestureRecognizerSortAndSendDelayedTouches 
+ 3609 10 UIKit        0x002adc53 
_UIGestureRecognizerUpdateObserver + 927 11 CoreFoundation    0x00da989b 
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ 
+ 27 12 CoreFoundation      0x00d3e6e7 __CFRunLoopDoObservers + 295  13 CoreFoundation    0x00d071d7 __CFRunLoopRun + 1575 14 CoreFoundation      0x00d06840 CFRunLoopRunSpecific + 208 15 CoreFoundation     0x00d06761 CFRunLoopRunInMode + 97 16 GraphicsServices     0x010001c4 GSEventRunModal + 217  17 GraphicsServices     0x01000289 GSEventRun + 115  18 UIKit 0x00028c93 UIApplicationMain + 1160 19      0x000027a9 main + 121 20 
         0x00002725 start + 53) terminate called after throwing an instance of 'NSException' 
+1

有一兩件事我注意到的是,你做的滾動視圖150倍東西contentSize當你創建151層的按鈕。 – onnoweb 2011-04-12 15:18:48

回答

2

是什麼ViewController該代碼是否仍然活着當按鈕被點擊?像這樣的錯誤(在這種情況下不相關的對象 - UIImageView)通常意味着你有一個指向已經釋放的內存的某個區域的指針,並用於其他事情(在這種情況下爲UIImageView)。

將一個NSLog()打印輸出添加到視圖控制器的-dealloc方法中,並確保它在點擊按鈕之前未被觸發。

實際上,在configureBestSellItems - NSLog(@"I am %x", self);(yes,%x,not%@)的開頭添加一個NSLog。這將打印出來的地址,你的view controller - 它與崩潰對象的地址進行比較(如「無法識別的選擇發送到實例0x681c2b0」 - 查看是否打印「我0x681c2b0」最初)

+0

@SVD - 我從子控制器中刪除了[super dealloc],這似乎工作,但我不確定基礎控制器是否會被釋放!? – TheLearner 2011-04-12 16:38:10

+1

刪除'[super dealloc]'是不對的。你顯然遇到了一個問題,無論哪個控制器意外地解除分配,而是通過移除「[super dealloc]」來解決問題,而不是解決它。您應該發佈更多與您的主視圖控制器實例化和呈現相關的代碼。這應該是問題所在。 – XJones 2011-04-12 16:41:55

+0

@TheLearner刪除[超dealloc]確認你有一個意外的發佈某處,但肯定不是一個解決方案。 – SVD 2011-04-12 16:52:41

0

當你alloced你UIButton,你標記,作爲autorelease,這可能是崩潰的原因是因爲存在由系統聲稱mainButton的possibilites,

UIButton *mainButton = [[[UIButton alloc]init] autorelease]; 

檢查並刪除autorelease,如果它能使UIButton作爲類變量或使用UIButton'sbuttonWithtype從系統獲取按鈕。

+0

刪除autorelease並從CALayer獲得相同的錯誤 – TheLearner 2011-04-12 15:24:16

+0

這不是問題所在。你需要釋放'mainButton'。你的autorelease是正確的。如果你刪除它,那麼你需要在將它添加到它的超級視圖後明確釋放'mainButton'。 – XJones 2011-04-12 16:33:13

相關問題