Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Diary App Using Core Data Inserting and Saving Data Inserting a Managed Object

Dee Greene
Dee Greene
8,508 Points

Apple Mach-O Linker Error

When running my application I keep getting:

duplicate symbol _THDiaryEntryMood in: /Users/deegreene/Library/Developer/Xcode/DerivedData/Diary-bijfeztneqrjqeeljxbefvflgvxc/Build/Intermediates/Diary.build/Debug-iphonesimulator/Diary.build/Objects-normal/x86_64/THNewEntryViewController.o /Users/deegreene/Library/Developer/Xcode/DerivedData/Diary-bijfeztneqrjqeeljxbefvflgvxc/Build/Intermediates/Diary.build/Debug-iphonesimulator/Diary.build/Objects-normal/x86_64/THDiaryEntry.o ld: 1 duplicate symbol for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

Is there any way I can fix this without having to start all over?

5 Answers

Dee Greene
Dee Greene
8,508 Points

To fix this error I replaced this line:

NS_ENUM(int16_t, THDiaryEntryMood) {

with:

typedef NS_ENUM(int16_t, THDiaryEntryMood) {

credit belongs to Gabe Nadel

Thanks for the update!

Gabe Nadel
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Gabe Nadel
Treehouse Guest Teacher

Do a search of your whole project for "THDiaryEntryMood" make sure you don't have duplicates. Assuming you don't, clean your project, quit XCode, then restart. See if that helps. If not, we'll take it from there.

Dee Greene
Dee Greene
8,508 Points

I do not have duplicates and I have tried restarting Xcode. what happened was when i first created "THDiaryEntry" it was created outside of the "Diary" project folder. So I deleted it and created another one that was inside of the folder that way my #import statements would be valid. I have went back to the folder in finder and deleted all references and the errors still exist. I'm stuck at this point lol

Gabe Nadel
seal-mask
.a{fill-rule:evenodd;}techdegree
Gabe Nadel
Treehouse Guest Teacher

If you think you have the error fixed, PLEASE share what you learned with the Community! It'll save others lots of trouble in the future :)

Dee Greene
Dee Greene
8,508 Points

actually i thought i did but really what i did was copy the code for "NS_ENUM(int16_t, THDiaryEntryMood)" into THDiaryEntry.m instead of THDiaryEntry.h. When i switched it back the error came back. Im very unsure of how to fix this now. Driving me crazy lol

Gabe Nadel
seal-mask
STAFF
.a{fill-rule:evenodd;}techdegree
Gabe Nadel
Treehouse Guest Teacher

Did you delete the actual FILES or just the references? You want to delete the actual duplicate files, if they still exist in the old spot. Also, are you building for simulator or device?

Dee Greene
Dee Greene
8,508 Points

I believe I deleted the files and moved them to the trash. I'm building for the simulator. However I can't build either way

Gabe Nadel
seal-mask
.a{fill-rule:evenodd;}techdegree
Gabe Nadel
Treehouse Guest Teacher

I'd suggest hunting around carefully in Finder to make sure you actually deleted any other copies of the files. If you find any, be sure to clean and restart xcode completely. If tha tdoesn't resolve your problem, I'd consult stackoverflow as there are LOTS of potential fixes for the common Mach-O errors. Good luck!

Dee Greene
Dee Greene
8,508 Points

think i have the error corrected. thank you!

Dee Greene
Dee Greene
8,508 Points

To fix my problem I:

  • deleted all files that contained "THDiaryEntryMood"

    • both in Xcode and in finder
  • cleaned Xcode

  • restarted xcode

-redid the "Create NSManagedObject Subclass" process

  • build Xcode
Gabe Nadel
seal-mask
.a{fill-rule:evenodd;}techdegree
Gabe Nadel
Treehouse Guest Teacher

Please show us the entire contents of:

  • THDiaryEntry.m
  • THDiaryEntry.h

and anywhere else where you reference:

THDiaryEntryMood

Dee Greene
Dee Greene
8,508 Points

THDiaryEntry.h

#import Foundation/Foundation.h
#import CoreData/CoreData.h

NS_ENUM(int16_t, THDiaryEntryMood) {
    THDiaryEntryMoodGood = 0,
    THDiaryEntryMoodAverage = 1,
    THDiaryEntryMoodBad = 2
};

@interface THDiaryEntry : NSManagedObject

@property (nonatomic, retain) NSString * body;
@property (nonatomic) NSTimeInterval date;
@property (nonatomic, retain) NSData * imageData;
@property (nonatomic, retain) NSString * location;
@property (nonatomic) int16_t mood;

@property (nonatomic, readonly) NSString *sectionName;

@end

THDiaryEntry.m

#import "THDiaryEntry.h"

@implementation THDiaryEntry

@dynamic body;
@dynamic date;
@dynamic imageData;
@dynamic location;
@dynamic mood;

- (NSString *)sectionName {
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:self.date];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"MMM yyy"];

    return [dateFormatter stringFromDate:date];
}

@end

These are the only places I can find that reference THDiaryEntryMood

and here is my current error...

duplicate symbol _THDiaryEntryMood in:
    /Users/deegreene/Library/Developer/Xcode/DerivedData/Diary-bijfeztneqrjqeeljxbefvflgvxc/Build/Intermediates/Diary.build/Debug-iphonesimulator/Diary.build/Objects-normal/i386/THNewEntryViewController.o
    /Users/deegreene/Library/Developer/Xcode/DerivedData/Diary-bijfeztneqrjqeeljxbefvflgvxc/Build/Intermediates/Diary.build/Debug-iphonesimulator/Diary.build/Objects-normal/i386/THDiaryEntry.o
duplicate symbol _THDiaryEntryMood in:
    /Users/deegreene/Library/Developer/Xcode/DerivedData/Diary-bijfeztneqrjqeeljxbefvflgvxc/Build/Intermediates/Diary.build/Debug-iphonesimulator/Diary.build/Objects-normal/i386/THNewEntryViewController.o
    /Users/deegreene/Library/Developer/Xcode/DerivedData/Diary-bijfeztneqrjqeeljxbefvflgvxc/Build/Intermediates/Diary.build/Debug-iphonesimulator/Diary.build/Objects-normal/i386/THEntryListViewController.o
ld: 2 duplicate symbols for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Gabe Nadel
seal-mask
.a{fill-rule:evenodd;}techdegree
Gabe Nadel
Treehouse Guest Teacher

Ok, if we look into the error, we see that the duplicate symbols are also found in:

  • THNewEntryViewController

and

  • THEntryListViewController

Let's see the complete code of those files too.

Also, why do you have:

import

import

Lastly, do you want the THDiaryEntry to be a subclass of NSManagedObject or just NSObject?

Dee Greene
Dee Greene
8,508 Points

the "<>" brackets took the rest of the code away from the #import

THNewEntryViewController.h

#import UIKit/UIKit.h

@interface THNewEntryViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *textField;

- (IBAction)doneWasPressed:(id)sender;
- (IBAction)cancelWasPressed:(id)sender;

- (void)insertDiaryEntry;
- (void)dismissSelf;

@end

THNewEntryViewController.m

#import "THNewEntryViewController.h"
#import "THDiaryEntry.h"
#import "THCoreDataStack.h"

@interface THNewEntryViewController ()

@end

@implementation THNewEntryViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

- (void)insertDiaryEntry {
    THCoreDataStack *coreDataStack = [THCoreDataStack defaultStack];
    THDiaryEntry *entry = [NSEntityDescription insertNewObjectForEntityForName:@"THDiaryEntry" inManagedObjectContext:coreDataStack.managedObjectContext];
    entry.body = self.textField.text;
    entry.date = [[NSDate date] timeIntervalSince1970];
    [coreDataStack saveContext];
}

- (void)dismissSelf {
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)doneWasPressed:(id)sender {
    [self insertDiaryEntry];
    [self dismissSelf];
}

- (IBAction)cancelWasPressed:(id)sender {
    [self dismissSelf];
}

@end

THEntryListViewController.h

#import UIKit/UIKit.h

@interface THEntryListViewController : UITableViewController

@end

THEntryListViewController.m

#import "THEntryListViewController.h"
#import "THCoreDataStack.h"
#import "THDiaryEntry.h"

@interface THEntryListViewController () <NSFetchedResultsControllerDelegate>

@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController;

@end

@implementation THEntryListViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    [self.fetchedResultsController performFetch:nil];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (NSFetchRequest *)entryListFetchRequest {
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"THDiaryEntry"];

    fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];

    return fetchRequest;
}

- (NSFetchedResultsController *)fetchedResultsController {
    if (_fetchedResultsController != nil) {
        return  _fetchedResultsController;
    }

    THCoreDataStack *coreDataStack = [THCoreDataStack defaultStack];
    NSFetchRequest *fetchRequest = [self entryListFetchRequest];

    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView reloadData];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return self.fetchedResultsController.sections.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections] [section];
    return [sectionInfo numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    THDiaryEntry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = entry.body;

    return cell;
}

For THDiaryEntry I created that by going to:

+ Diary.xcdatamodeld
+ ENTITIES
+ THDiaryEntry
+ Editor
+ Create NSManagedObject Subclass

This happened for me too. It's driving me nuts.

I deleted the references and files for the THDiaryEntry. Then I did a clean and restart. Then I started stepping through the process.

First thing that is different for me is that the default location for the THDiaryEntry when doing the "Create NSManagedObject Subclass" step is outside of the diary folder, unlike the location in the video. However, the build still works. After adding the import to the NewEntryViewController, the build works.

The build fails for me as soon as I add the ENUM to the THDiaryEntry.h file.

I added the code to insert the managed object in NewEntryViewController, and as long as I have the ENUM commented out, the build works.

Found the answer in another thread. See https://teamtreehouse.com/community/linker-error

Added extern in front of the ENUM, and I'm back in business!