2011-04-12 21 views
5

estoy recibiendo el mensaje de error que no puedo entender por qué su suceso, porque no estoy usando cualquier UIImageView. A veces recibo el mismo error pero es un CALayer?!?selector no reconocido enviado a la instancia

Vale la pena mencionar también que tengo 2 nibs y 2 controladores y un controlador de base donde reside el código.

EDIT:

Ésta es la estructura de mi proyecto

MainViewController & su punta - HomeViewController en punta

MainViewController-paisaje & su punta - HomeViewController-paisaje en punta

HomeViewControllerBase - sin punta - Clase base donde todos o existe el código de configuración de artículos y utlets. - Las dos clases secundarias utilizan los puntos de venta a continuación. - Las salidas están vinculadas a los controles en cada una de las puntas principales.

HomeViewController - hereda de HomeViewControllerBase

HomeViewController-paisaje - hereda de HomeViewControllerBase

Así qué está sucediendo es que la clase niño está tratando de dealloc su clase base (que tiene todos los puntos de venta en el mismo) . Lo he diseñado de esta manera para evitar la duplicación de código en los diferentes viewcontrollers de orientación.

@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

Una cosa que estoy notando es que a tomar la contentSize del ScrollView 150 veces algo mientras se está creando 151 botones. – onnoweb

Respuesta

2

¿El lo ViewController este código es de todavía vivo cuando se pulsa el botón? Un error como este (objeto no relacionado - UIImageView en este caso) por lo general significa que tiene un puntero a un área de la memoria que se ha liberado y reutilizado para otra cosa (UIImageView en este caso).

Agregue una impresión NSLog() al método -dealloc del controlador de vista y asegúrese de que no se dispare antes de tocar el botón.

En realidad, agregue un NSLog más al comienzo de configureBestSellItems - NSLog(@"I am %x", self); (sí,% x, no% @).Esto imprimirá la dirección de su view controller - compararla con la dirección del objeto estrellarse (como en "Selector no reconocido enviado a la instancia 0x681c2b0" - ver si se imprime "Estoy 0x681c2b0" inicialmente)

+0

@SVD - Quité el [super dealloc] de los controladores secundarios y pareció funcionar, sin embargo, no estoy seguro de si el controlador base va a ser lanzado alguna vez. – TheLearner

+1

Quitar '[super dealloc]' es lo incorrecto. Claramente tienes un problema con cualquier controlador que sea 'auto' desasignado inesperadamente, pero al eliminar '[super dealloc] 'estás ocultando el problema, no resolviéndolo. Debería publicar más código relacionado con la instancia y presentación de su controlador de vista principal. Eso debería ser donde está el problema. – XJones

+0

@TheLearner eliminando [super dealloc] confirma que tiene una versión inesperada en algún lugar, pero ciertamente no es una solución. – SVD

0

Cuando alloced su UIButton, se encuentra en posición de que como autorelease, esto podría ser la razón del accidente debido a que hay posibilidades de reclamar mainButton por el sistema,

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

Verifique con la eliminación de autorelease y si funciona haga su UIButton como variable de clase o use UIButton'sbuttonWithtype para obtener el botón del sistema.

+0

Se ha eliminado la liberación automática y se obtiene el mismo error, excepto en CALayer – TheLearner

+0

Este no es el problema. Debes liberar 'mainButton'. Su autorrelease fue correcto. Si lo elimina, debe liberar explícitamente 'mainButton' después de agregarlo a su supervista. – XJones

Cuestiones relacionadas