Хобрук: Ваш путь к мастерству в программировании

Зарегистрировать Nib в ViewDidLoad Thread 1, исключая плохое представление таблицы доступа

Я получаю сообщение об ошибке Thread 1, EXC: BAD ACCESS на моем [self.tableView registerNib:nib forCellReuseIdentifier:@"InboxCell"]; линия. Все работало нормально, но затем я попытался загрузить файл быстрого доступа BackroundView, что было скорее головной болью, чем того стоило.

Я удалил быстрый файл BackgroundView и очистил его, но теперь у меня есть ошибка, которую я не могу понять. У меня есть пользовательская ячейка InboxCell.xib. Пожалуйста, держите меня за руку. Любая помощь приветствуется! Вот мой код:

//InboxTableViewController.h
    #import "InboxCell.h"


@interface InboxTableViewController : UITableViewController

//this is property for the data source
@property (nonatomic, strong) NSArray *messages;

//something for showing image
@property (nonatomic, strong) PFObject *selectedMessage;

//for showing video
@property (nonatomic, strong) MPMoviePlayerController *moviePlayer;


- (IBAction)logout:(id)sender;

//set thumbnail
@property (nonatomic, strong) UIImage *thumbnail;

-(void)setThumbnailFromImage:(UIImage *)image;

@end


//.m
@interface InboxTableViewController ()




@end

@implementation InboxTableViewController

-(void)loadView
{

}

- (void)viewDidLoad {
    [super viewDidLoad];

    //THIS IS CUSTOM CELL!!!!!!!
    UINib *nib = [UINib nibWithNibName:@"InboxCell" bundle:nil];
    //register this nib to contain cell
/*THIS IS EXC ERROR*/
    [self.tableView registerNib:nib  forCellReuseIdentifier:@"InboxCell"];

    //video alloc here so its reused for every video in inbox.
    self.moviePlayer = [[MPMoviePlayerController alloc] init];

    //Determining if a current user is logged in
    PFUser *currentUser = [PFUser currentUser];
    if (currentUser) {
        NSLog(@"%@", currentUser.username);
    } else {
        [self performSegueWithIdentifier:@"showLogin" sender: self];

    }



}


////      In case it hasnt been logged in after a while
- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];

    //return nav and controller bar
    [self.navigationController.navigationBar setHidden:NO];
    [self.tabBarController.tabBar setHidden:NO];

    PFQuery *query = [PFQuery queryWithClassName:@"Messages"];
    // prevents error when running for first time in a while
    if ([[PFUser currentUser] objectId] == nil) {
        NSLog(@"No objectID");
    } else {
        [query whereKey:@"recipientIds" equalTo:[[PFUser currentUser] objectId]];
        [query orderByDescending:@"createdAt"];
        [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            if (error) {
                NSLog(@"error %@ %@", error, [error userInfo]);
            } else {
                self.messages = objects;
                [self.tableView reloadData];
                NSLog(@"Got %lu messages", (unsigned long)[self.messages count]);
            }
        }];
    }
}




- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showLogin"]) {
        [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
    }
    else if ([segue.identifier isEqualToString:@"showImage"]) {
        //setting it so image tab wont pop up
        [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
        ImageViewController *imageViewController = (ImageViewController *)segue.destinationViewController;
        imageViewController.message = self.selectedMessage;
    }
}


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    self.selectedMessage = [self.messages objectAtIndex:indexPath.row];
    NSString *fileType = [self.selectedMessage objectForKey:@"fileType"];
    if ([fileType isEqualToString:@"image"]) { //if image file
        [self performSegueWithIdentifier:@"showImage" sender:self];
    }
    else {
        //file type is video
        PFFile *videoFile = [self.selectedMessage objectForKey:@"file"]; //getting the file
        //now getting the URL property which is a string
        NSURL *fileUrl = [NSURL URLWithString:videoFile.url];
        //set the url for the movie player
        self.moviePlayer.contentURL = fileUrl;
        //prepare for file
        [self.moviePlayer prepareToPlay];

        //this is a quick thumbnail while it loads
        //              [[self.moviePlayer ]; NOT WORKING HERE

        //Add video to view controller so you can see it
        [self.view addSubview:self.moviePlayer.view];
        //setting it to screen size CAN SET TO ANYSIZE!!!!!!!
        [self.moviePlayer setFullscreen:YES animated:YES];
    }
/*    //this portion is to delete it after its viewed
    NSMutableArray *recipientIds = [NSMutableArray arrayWithArray:[self.selectedMessage objectForKey:@"recipientIds"]];

    //this is for each one individually
   if ([recipientIds count] == 1) {
        //last recipient delete
        [self.selectedMessage deleteInBackground];
    }
    else {
        //remove the recipients and save it
        [recipientIds removeObject:[[PFUser currentUser] objectId]];
        //now you have to update recipients array with new data
        [self.selectedMessage setObject:recipientIds forKey:@"recipientIds"];
        [self.selectedMessage saveInBackground];

    }   */
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    // always use the count of data source
    return [self.messages count];
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    /*CUSTOM CELL CODE */
    InboxCell *cell = [tableView dequeueReusableCellWithIdentifier:@"InboxCell" forIndexPath:indexPath];
    PFObject *message = [self.messages objectAtIndex:indexPath.row];
    cell.titleLabel.text = [message objectForKey:@"senderName"];
    //Date 
    NSDate *updated = [message updatedAt];
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
    [dateFormat setDateFormat:@"EEE, MMM d, h:mm a"];
    cell.createdAtLabel.text = [NSString stringWithFormat:@"Filmed At: %@", [dateFormat stringFromDate:updated]];

    //    customizing the image next to the message to determine whether its a video or image.
    NSString *fileType = [message objectForKey:@"file_type"];
    if ([fileType isEqualToString:@"image"]) {  // must add icons
        cell.thumbnailView.image = [UIImage imageNamed: @"icon_image.png"];
        //                              cell.imageView.image is the way to have a picture in a cell.
    }
    else {
        cell.thumbnailView.image = [UIImage imageNamed:@"icon_video"];
    }



    return cell;
}

//this is used as a thumbnail before video plays
//- (UIImage *)thumbnailFromVideoAtURL:(NSURL *)url
//{
//    AVAsset *asset = [AVAsset assetWithURL:url];
//    
//    //  Get thumbnail at the very start of the video
//    CMTime thumbnailTime = [asset duration];
//    thumbnailTime.value = 0;
//    
//    //  Get image from the video at the given time
//    AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
//    
//    CGImageRef imageRef = [imageGenerator copyCGImageAtTime:thumbnailTime actualTime:NULL error:NULL];
//    UIImage *thumbnail = [UIImage imageWithCGImage:imageRef];
//    CGImageRelease(imageRef);
//    
//    return thumbnail;
//}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0) {
        return 100;
    }
    else {
        return 100;
    }
}

- (IBAction)logout:(id)sender {
    [PFUser logOut];
    [self performSegueWithIdentifier:@"showLogin" sender:self];
}

- (IBAction)refresh:(id)sender {

     [self.tableView reloadData];
    [sender endRefreshing];
}

//setting thumbnail for cell
-(void)setThumbnailFromImage:(UIImage *)image
{
    CGSize origImageSize = image.size;

    CGRect newRect = CGRectMake(0, 0, 104, 76);

    float ratio = MAX(newRect.size.width /  origImageSize.width, newRect.size.height /  origImageSize.height);

    UIGraphicsBeginImageContextWithOptions(newRect.size, NO, 0.0);

    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:newRect cornerRadius:5.0];

    [path addClip];

    CGRect projectRect;
    projectRect.size.width = ratio * origImageSize.width;
    projectRect.size.height = ratio * origImageSize.height;
    projectRect.origin.x = (newRect.size.width - projectRect.size.width) / 2.0;
    projectRect.origin.y = (newRect.size.height - projectRect.size.height) / 2.0;

    [image drawInRect:projectRect];

    UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
    self.thumbnail = smallImage;

    UIGraphicsEndImageContext();

}


@end

  • Не переопределяйте loadView и оставьте его пустым. Плохо. Удалите этот метод. 16.09.2015
  • Чувак, спасибо, я работал над этим около 4 утра и забыл, что собирался что-то добавить. Ты == классный 16.09.2015

Ответы:


1

Ваша проблема вызвана пустым методом loadView. Никогда не оставляйте этот метод пустым. Либо удалите метод, либо дайте ему правильную реализацию создания основного представления контроллера представления и настройки self.view.

16.09.2015
Новые материалы

Решения DBA Metrix
DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

Начало работы с Блум
Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

Создание кнопочного меню с использованием HTML, CSS и JavaScript
Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

Внедрите OAuth в свои веб-приложения для повышения безопасности
OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

Классы в JavaScript
class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

Как свинг-трейдеры могут использовать ИИ для больших выигрышей
По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

Как построить любой стол
Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...