无法识别的选择器发送到实例 [英] unrecognized selector sent to instance

查看:122
本文介绍了无法识别的选择器发送到实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到以下错误消息,我不能理解为什么它的发生,因为我不使用任何UIImageView。有时我得到相同的错误,但它的CALayer?!?



它的价值还提到我有2个nibs和2个控制器和一个基本控制器,这个代码驻留。 / p>

编辑:



这是我的项目结构



MainViewController&它的nib
- nib中的HomeViewController



MainViewController-Landscape&它的nib
- HomeViewController - nib中的横向



HomeViewControllerBase - 无nib
- 所有插座和项目配置代码存在的基类。
- 下面的两个子类使用插座。



HomeViewController
- 继承自HomeViewControllerBase



HomeViewController-Landscape
- 继承自HomeViewControllerBase



因此,发生的是子类尝试释放其基类所有的出口在它)。我已经设计了这样的方式,以避免重复的代码在不同的方向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:@MainViewControllerbundle:nil];

if(self)
{
isShowingLandscapeView = NO;
self.landscapeViewController = [[[MainViewController_Landscape alloc]
initWithNibName:@MainViewController-Landscapebundle: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 (@畅销商品);
}

- (void)configureBestSellItems
{
[self startRetrievingRegions];

//从我们的bundle中加载所有的图像并将它们添加到滚动视图
// 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];



//将每个框架设置为默认高度和宽度,当我们调用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]; //现在将照片以串行布局放在scrollview中
}


//在加载视图之后(通常是从nib)执行viewDidLoad进行其他设置。
- (void)viewDidLoad
{
[super viewDidLoad];
[self configureBestSellItems];
}

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

//以水平连续方式重新定位所有图像子视图
CGFloat curXLoc = 0;
for(在子视图中查看)
{
if([view isKindOfClass:[UIButton class]]&& view.tag> 0)
{
CGRect frame = view.frame;
frame.origin = CGPointMake(curXLoc,0);
view.frame = frame;

curXLoc + =(kScrollObjWidth + kScrollObjPadding);
}
}

//设置内容大小以便可以滚动
[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]; //当我删除这个工作
}

@end

@implementation HomeViewController_Landscape

- (void)dealloc
{
[super dealloc]; //当我删除它它工作
}

@end



< HR>

   -  [UIImageView的bestSellItemTapped:]:无法识别的选择发送到实例0x681c2b0 2011-04-12 15:45:26.665 [21532:207] ***终止应用程序由于未捕获的异常'NSInvalidArgumentException',原因:' -  [UIImageView的bestSellItemTapped:]:无法识别的选择发送到实例0x681c2b0'
***在第一掷调用堆栈:(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::从:forEvent: ] + 119 6 UIKit的0x000aa799 - [UIControl sendAction:到:forEvent:] + 67 7 UIKit的0x000acc2b - [UIControl(内部)
_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主+ 121 20
0x00002725启动+ 53)投掷后终止叫'NSException'的实例


解决方案

c $ c> ViewController 这个代码是从按钮被点击时仍然活着的?这样的错误(在这种情况下,不相关的对象 - UIImageView )通常意味着你有一个指针指向已经释放和重用的内存的某个区域(<$



添加 NSLog()打印输出到视图控制器的-dealloc方法,并确保在点击按钮之前没有触发。



实际上,添加一个NSLog到 configureBestSellItems - NSLog(@I am%x,self); (yes,%x,not%@)。这将打印出您的视图控制器的地址 - 与崩溃对象的地址进行比较(如在无法识别的选择器发送到实例 0x681c2b0 - 看看它是否打印我是0x681c2b0最初)


I am getting the following error message which I cannot understand why its happening because I am not using any UIImageView. Sometimes I get the same error but its a CALayer?!?

Its worth also mentioning that I have 2 nibs and 2 controllers and a base controller where this code resides.

EDIT:

This is the structure of my project

MainViewController & its nib - HomeViewController in nib

MainViewController-Landscape & its nib - HomeViewController-Landscape in nib

HomeViewControllerBase - no nib - Base class where all outlets and item configuration code exists. - Outlets are used by both child classes below. - Outlets are linked to controls in each of the main nibs.

HomeViewController - Inherits from HomeViewControllerBase

HomeViewController-Landscape - Inherits from HomeViewControllerBase

So whats happening is that the child class is trying to dealloc its base class (which has all the outlets in it). I have designed it this way to avoid duplication of code in the different orientation 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'

解决方案

Is the whatever ViewController this code is from still alive when the button is tapped? An error like this (unrelated object - UIImageView in this case) usually means you have a pointer to some area of the memory that has been released and reused for something else (UIImageView in this case).

Add an NSLog() printout to the -dealloc method of the view controller and make sure it's not fired before you tap the button.

Actually, add one more NSLog to the beginning of configureBestSellItems - NSLog(@"I am %x", self); (yes, %x, not %@). This will print out the address of your view controller - compare it with the address of the crashing object (as in "unrecognized selector sent to instance 0x681c2b0" - see if it prints "I am 0x681c2b0" initially)

这篇关于无法识别的选择器发送到实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆