-2

  I am very new to Objective-C . I am trying to send an object of type User(made with core data) from SingupViewController to its delegate ViewController. However I get this error that you get from what I've read because I am double instantiating memory for the same object ? . The error is as follows :

[User managedObjectModel]: unrecognized selector sent to instance 0x10ca90560
2015-03-14 03:44:49.613 Honk2[302:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[User managedObjectModel]: unrecognized selector sent to instance 0x10ca90560'

  The code for SingupViewController.h is :

#import <UIKit/UIKit.h>
#import "User.h"


@protocol SingupDelegate <NSObject>

- (void)signUp;
- (void)cancelPressDel;
- (void)savePress:(User *)addUser;

@end

@interface SingupViewController : UIViewController

@property (nonatomic, weak) id<SingupDelegate> delegate;

@end

The code for SingupViewController.m is:

import "SingupViewController.h"
#import "UIViewController+MJPopupViewController.h"
#import "UIViewController+MJPopupViewController.h"
#import "LoginViewController.h"
#import "ViewController.h"
#import "CoreViewController.h"

@interface SingupViewController () <UITextFieldDelegate>
{

    UILabel *titleApp;

    UITextField *username;
    UITextField *password;
    UITextField *email;
    UIButton *signUp;
    UIButton *cancel;
}
    @property(strong,nonatomic)User *thenewUser;

@end

@implementation SingupViewController
-(void)onSignUpPressed{

    _thenewUser.name = username.text;
    _thenewUser.email = email.text;
    _thenewUser.password = password.text;

    if([[self delegate] respondsToSelector:@selector(savePress:)]) {
        [[self delegate] savePress:_thenewUser];

    }

}

@end

The code for ViewController.h is:

#import <UIKit/UIKit.h>
#import "CoreViewController.h"
#import "User.h"

@interface ViewController : CoreViewController <NSFetchedResultsControllerDelegate>

@end

And the code for ViewController.m is:

#import "ViewController.h"
#import "UIViewController+MJPopupViewController.h"
#import "LoginViewController.h"
#import "SingupViewController.h"
#import "AppDelegate.h"
#import "CoreViewController.h"


@interface ViewController () <LoginDelegate, SingupDelegate>
{
    LoginViewController *login;
    SingupViewController *singup;
}
    @property (nonatomic, strong) NSManagedObjectContext *managedObject;
    @property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;

@end

@implementation ViewController
-(void)savePress:(User *)addUser{

    NSEntityDescription *description = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:[self managedObjectContext]];

    NSManagedObject *newUser = [[NSManagedObject alloc] initWithEntity:description insertIntoManagedObjectContext:[self managedObjectContext]];

    [newUser setValue:addUser.name forKey:@"name"];
    [newUser setValue:addUser.email forKey:@"email"];
    [newUser setValue:addUser.password forKey:@"password"];

    NSError *error = nil;

    if(![newUser.managedObjectContext save:&error]){
        NSLog(@"invatam si noi sa codam?");
    }
    else{
        NSLog(@"Hai ca am invatam sa codat");
    }


    [self dismissPopupViewControllerWithanimationType:MJPopupViewAnimationSlideTopBottom];
}
-(NSManagedObjectContext*)managedObjectContext{
    return[(AppDelegate*)[[UIApplication sharedApplication]delegate]managedObjectContext];
}

The User.h is the one given by Xcode :

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class Tweet;

@interface User : NSManagedObject

@property (nonatomic, retain) NSString * email;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * password;
@property (nonatomic, retain) NSSet *tweets;
@end

@interface User (CoreDataGeneratedAccessors)

- (void)addTweetsObject:(Tweet *)value;
- (void)removeTweetsObject:(Tweet *)value;
- (void)addTweets:(NSSet *)values;
- (void)removeTweets:(NSSet *)values;

@end

And this is the User.m also not touched:

#import "User.h"
#import "Tweet.h"


@implementation User

@dynamic email;
@dynamic name;
@dynamic password;
@dynamic tweets;

@end

The error happens when I try to save the object. Can anyone tell me what I am allocating wrong ? Or what the fault is ?

Lucian Tarna
  • 1,806
  • 4
  • 25
  • 48
  • 1
    Could you post some code about `User` class? – Zigii Wong Mar 14 '15 at 11:02
  • possible duplicate of [How can I debug 'unrecognized selector sent to instance' error](http://stackoverflow.com/questions/25853947/how-can-i-debug-unrecognized-selector-sent-to-instance-error) – Hot Licks Mar 14 '15 at 11:23

1 Answers1

1

The error is because you are sending a managedObjectModel to your User object and User cannot respond to that.

What's happening is when instantiating an NSEntityDescription you should use the following code:

[NSEntityDescription entityForName:@"User" inManagedObjectContext:context];

What you are doing is instantiating a User object not an NSEntityDescription object. Then this line:

NSManagedObject *newUser = [[NSManagedObject alloc] initWithEntity:description insertIntoManagedObjectContext:[self managedObjectContext]];

the description is actually a User object not an NSEntityDescription object.

EDIT a few pointers:

1) in the onSignUpPressed if possible you should make a new user and add it to the context there and then but if you really want to call savePress: do this:

-(void)onSignUpPressed{

    if([[self delegate] respondsToSelector:@selector(savePress:)]) {
        [[self delegate] savePress:@{@"UName":username.text, @"Email":email.text, @"PWord":password.text}];

    }
}

What you are doing here is sending a dictionary with all the appropriate values to the delegate.

Then in the savePress:

-(void)savePress:(NSDictionary *)dict{

    NSEntityDescription *description = [NSEntityDescription entityForName:@"User" inManagedObjectContext:[self managedObjectContext]];

    NSManagedObject *newUser = [[NSManagedObject alloc] initWithEntity:description insertIntoManagedObjectContext:[self managedObjectContext]];

    [newUser setValue:dict[@"UName"] forKey:@"name"];
    [newUser setValue:dict[@"Email"] forKey:@"email"];
    [newUser setValue:dict[@"PWord"] forKey:@"password"];

    NSError *error = nil;

    if(![newUser.managedObjectContext save:&error]){
        NSLog(@"invatam si noi sa codam? Error: %@", error.localizedDescription);
    }
    else{
        NSLog(@"Hai ca am invatam sa codat");
    }


    [self dismissPopupViewControllerWithanimationType:MJPopupViewAnimationSlideTopBottom];
}

When you use CoreData you really need to have a structure that is planned and that you stick to.

Rob Sanders
  • 5,197
  • 3
  • 31
  • 58
  • User *newUser = [[User alloc] initWithEntity:description insertIntoManagedObjectContext:[self managedObjectContext]]; doing this doesn't fix it either . How can I save newUser in the DB ? – Lucian Tarna Mar 14 '15 at 11:03
  • It's because the `description` variable isn't an `NSEntityDescription` the return value for `NSEntityDescription *description = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:[self managedObjectContext]];` is a `User` object not a `NSEntityDescription` object. Check the [documentation](https://developer.apple.com/library/ios/documentation/Cocoa/Reference/CoreDataFramework/Classes/NSEntityDescription_Class/index.html#//apple_ref/occ/clm/NSEntityDescription/entityForName:inManagedObjectContext:) – Rob Sanders Mar 14 '15 at 11:09
  • wait, I get what you are saying. Thank you very much RASS , sorry I shall try to pay more attention in the future , I was just following a tutorial and I was trying to add stuff that I heard so I kinda get stuck sometimes .. since I don't go along with the tutorial 100% – Lucian Tarna Mar 14 '15 at 11:17
  • _thenewUser.email = email.text; why doesn't it give the email.text value to _thenewUser.email ? if you have the spare time:D – Lucian Tarna Mar 14 '15 at 13:41
  • 1
    Having a look I can't see any code for instantiating _thenewUser, so as far as I can see you are setting the values to a nil reference. What you need to do is:`self.thenewUser = [User alloc] initWithEntity:[NSEntityDescription entityForName:@"User" inManagedObjectContext:[self managedObjectContext]] insertIntoManagedObjectContext:nil];` just before you set the values. – Rob Sanders Mar 14 '15 at 13:51
  • you are perfectly right, I was trying to do it like _newUser = [[User alloc] init] and xcode was being mean to me :. Thank you very much again! – Lucian Tarna Mar 14 '15 at 13:54