簡體   English   中英

Xcode 無法識別的選擇器錯誤

[英]Xcode Unrecognized Selector Error

對於我正在編寫的應用程序的這一部分,我遇到了很多問題,我相信這里的人已經厭倦了我,所以我將嘗試在這篇文章中解決我所有的問題。 我正在開發一個行為類似於照片庫的應用程序,並且我正在實施讓用戶從他們的畫廊中刪除照片的選項。 為此,我決定在每張圖片上放置一個不可見的按鈕。 當用戶點擊“編輯”按鈕時,每張圖片上的隱藏刪除按鈕將變為活動狀態。 為簡單起見,我在每個隱藏按鈕上使用相同的 IBOutlet,並且我在 Interface Builder 中適當地標記了每個按鈕。 當用戶點擊圖片上的按鈕時,會出現一個警告視圖,詢問他們是否真的要刪除它。 如果他們單擊“是”,我將調用 removeObjectAtIndex 並從 UI 中刪除圖像。 但是,當我在警報視圖中單擊“是”時,我收到一條來自 Xcode 的錯誤,指出:

2012-04-04 11:26:40.484 AppName[608:f803] -[UIButton setImage:]: 無法識別的選擇器發送到實例 0x6a922c0

2012-04-04 11:26:40.485 AppName[608:f803] 由於未捕獲的異常“NSInvalidArgumentException”而終止應用程序,原因:“-[UIButton setImage:]:無法識別的選擇器已發送到實例 0x6a922c0” *

幾個小時以來,我一直試圖弄清楚是什么原因造成的,但無濟於事。 我沒有在我的代碼中的任何地方設置 UIButton 的圖像。 我在 IB 中做過,但我只是將按鈕類型設置為自定義,以便它們看起來不可見。 我將在下面發布我的整個文件,我在我的代碼中找不到任何問題,所以非常感謝任何幫助。 謝謝。 編輯這是代碼的當前版本:

    - (IBAction)grabImage {
    self.imgPicker = [[UIImagePickerController alloc] init];
    self.imgPicker.delegate = self;
    self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        _popover = [[UIPopoverController alloc] initWithContentViewController:imgPicker];
        [_popover presentPopoverFromRect:self.imageView.bounds inView:self.imageView permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    } 

    else {
        [self presentModalViewController:imgPicker animated:YES];
    }
    [self.imgPicker resignFirstResponder];
}
// Sets the image in the UIImageView
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo {
    if (imageView.image == nil) {
        imageView.image = img;

        self.array = [NSMutableArray arrayWithObject:[NSData dataWithData:UIImagePNGRepresentation(imageView.image)]];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;

    }

    if (imageView2.image == nil) {
        imageView2.image = img;
        NSLog(@"The image is a %@", imageView);
        [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView2.image)]];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
    }

    if (imageView3.image == nil) {
        imageView3.image = img;

        [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView3.image)]];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
    }

    if (imageView4.image == nil) {
        imageView4.image = img;

        [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView4.image)]];

        [picker dismissModalViewControllerAnimated:YES];
        [self.popover dismissPopoverAnimated:YES];
        return;
}
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = NSLocalizedString(@"Photo Gallery", @"Photo Gallery");
        self.tabBarItem.image = [UIImage imageNamed:@"42-photos.png"];
    }
    return self;
}
////start of saving////


- (void)applicationDidEnterBackground:(UIApplication*)application {
    NSLog(@"Image on didenterbackground: %@", imageView);
    self.array = [NSMutableArray arrayWithObject:[NSData dataWithData:UIImagePNGRepresentation(imageView.image)]];

    [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView2.image)]];
     [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView3.image)]];
      [self.array addObject:[NSData dataWithData:UIImagePNGRepresentation(imageView4.image)]];

            [self.user setObject:self.array forKey:@"images"];
    [user synchronize];

            }

- (void)viewDidLoad
    {
        self.user = [NSUserDefaults standardUserDefaults];
        NSLog(@"It is %@", self.user);
        self.array = [[self.user objectForKey:@"images"]mutableCopy];
        imageView.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:0]];
        imageView2.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:1]];
        imageView3.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:2]];
        imageView4.image = [[UIImage alloc] initWithData:[self.array objectAtIndex:3]];



        UIApplication *app = [UIApplication sharedApplication];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationDidEnterBackground:)
                                                     name:UIApplicationDidEnterBackgroundNotification
                                                   object:app];

        backToGalleryButton.hidden = YES;
        tapToDeleteLabel.hidden = YES;
        deleteButton1.hidden = YES;
        [super viewDidLoad];

    }




///// shows the hidden and invisible "delete" button over each photo.
- (IBAction)editButtonPressed:(id)sender {
    grabButton.hidden = YES;
    editButton.hidden = YES;
    backToGalleryButton.hidden = NO;
    tapToDeleteLabel.hidden = NO;
    deleteButton1.hidden = NO;
}
////

// This is when the user taps on the image to delete it.
- (IBAction)deleteButtonPressed:(id)sender {
    NSLog(@"Sender is %@", sender);
    UIAlertView *deleteAlertView = [[UIAlertView alloc] initWithTitle:@"Delete"
                                                              message:@"Are you sure you want to delete this photo?"
                                                             delegate:self
                                                    cancelButtonTitle:@"No"
                                                    otherButtonTitles:@"Yes", nil];
    [deleteAlertView show];
    int imageIndex = ((UIButton *)sender).tag;
    deleteAlertView.tag = imageIndex;

}

- (void)alertView: (UIAlertView *) alertView 
clickedButtonAtIndex: (NSInteger) buttonIndex
{


    if (buttonIndex != [alertView cancelButtonIndex]) {
        NSLog(@"User Clicked Yes. Deleting index %d of %d", alertView.tag, [array count]);
        NSLog(@"The tag is %i", alertView.tag);
        [self.array removeObjectAtIndex: alertView.tag];
        NSLog(@"After deleting item, array count  = %d", [array count]);
    NSLog(@"Returned view is :%@, in view: %@", [self.view viewWithTag:alertView.tag], self.view);
        ((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil;
    }

    [self.user setObject:self.array forKey:@"images"];
}

更新:我添加了斷點,發現((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil; 是導致崩潰的線路,但我仍然不明白為什么。

我沒有看到setImage:在您粘貼到問題中的任何代碼中被調用,但我可以告訴您: UIButtonsetImage方法實際上需要一個按鈕 state 作為第二個參數。

例如

[UIButton setImage: forState:]

我已經為您鏈接了 Apple 的文檔。

如果您對setImage:的調用沒有第二個參數,那將解釋您看到的“無法識別的選擇器錯誤”。

這是對@MichaelDautermann 的擴展,他很好地指出 UIButton 有一個 setImage:forState: 方法,但沒有 setImage 方法。 但是,您正在調用 set image。 不是在按鈕上,而是在您說 imageView.image 和 imageView2.image 時。 這會調用圖像視圖的 setter 方法。 我會設置一個斷點(或使用 NSLog 和 %@ 項)以確保 imageView 實際上是 imageView 而不是按鈕。 如果它以某種方式從您下方發生變化,則可能是導致問題的原因。 只需在這兩條線上設置一個斷點,看看你是否能通過它們。

此外,如果 Xcode 沒有提示您實際是哪一行導致了問題,請檢查您的崩潰日志。 符號化的日志將為您提供行號。 或者,一種不太直接的方法是在您在答案中提供的方法的末尾設置斷點,然后查看您通過了多少。 一旦崩潰,您可以縮小導致您痛苦的方法的范圍,然后開始在該方法內設置斷點,直到您到達有問題的行。

更新:您在評論中說 ((UIImageView *)[self.view viewWithTag:alertView.tag]).image =nil 是您所擁有的,但 self.view 是一個 UIControl。 改變演員表不會影響結果。 您要刪除其圖像的 UIImageView 是 UIControl 的子視圖嗎? 否則,您將永遠無法從 viewWithTag 取回圖像視圖。 一般來說,self.view 指的是視圖控制器的視圖,所以如果你得到一個 UIControl,我的假設是你的整個視圖是一個 UIControl,或者你在錯誤的 class 中執行此操作。你在哪個 class 中執行此操作,它是什么的子類? 看來您是在視圖 controller 中執行此操作,但我只是想確定一下。 同樣,在任何一種情況下(UIControl 或 UIImageView),class 都不響應 setImage。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM