Linker "Duplicate Symbol" error due to circular reference - ios

I have two header of a class and it's extension(generated by Xcode for NSManaged object). But I'm getting a linker error and I figured out it was due to a circular reference.
Conversation+CoreDataClass.h
NS_ASSUME_NONNULL_BEGIN
#interface Conversation : NSManagedObject
#end
NS_ASSUME_NONNULL_END
#import "Conversation+CoreDataProperties.h"
Conversation+CoreDataProperties.h
#import "Conversation+CoreDataClass.h"
NS_ASSUME_NONNULL_BEGIN
#interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
#end
NS_ASSUME_NONNULL_END
You can clearly see the circular reference here. I found this question where the problem was to add a #class declaration and remove the header. So I commented out the import statement in the Conversation+CoreDataProperties.h and added #class Conversation;. Now two errors pop up saying it's an undefined class. Have attached the screenshot of the error below. I don't quite understand why this is happening and what I need to do to fix it. Any help is much appreciated. Thanks!
Linker error
duplicate symbol _OBJC_CLASS_$_Conversation in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o
duplicate symbol _OBJC_METACLASS_$_Conversation in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/Conversation+CoreDataClass.o
duplicate symbol _OBJC_CLASS_$_ConversationDate in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o
duplicate symbol _OBJC_METACLASS_$_ConversationDate in:
/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-gbhivuwptwzhkldfbmjghkokozgn/Build/Intermediates/xxx.build/Debug-iphoneos/xxx.build/Objects-normal/arm64/ConversationDate+CoreDataClass.o
ld: 4 duplicate symbols for architecture arm64 clang: error: linker
command failed with exit code 1 (use -v to see invocation)

So I commented out the import statement in the Conversation+CoreDataProperties.h and added #class Conversation;.
You may only do this if you're aren't using any of the Convention class's interface (for instance declaring a property of type Convention. You can't do this if you're extending Convention via a category or class extension.
You have a legit circular reference here you must resolve. You can either:
Move the class and the category into the same source file (if there's no special reason this needs to be in a category you could just move the declaration of fetchRequest into the class itself).
Stop importing +CoreDataProperties.h in the class header, and import it instead wherever callers need to be calling fetchRequest.

the duplicate symbols warning do result because
You have the class multiple times in your project and the compiler does not know, which to choose (then it is mostly a duplicate linking error)
There is something wrong with your ConversationDate+CoreDataClass
Just a question that raised from your source code: why do you import an extension of the class you want to extend?
#import "Conversation+CoreDataClass.h"
#interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
#end
All the extension class usually needs to know are basically the classes they extend:
#import "Conversation.h"
#interface Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest;
#end
Only the implementation file (.m) would have to import the header file. E.g:
#import "Conversation+CoreDataClass.h"
#implementation Conversation (CoreDataProperties)
+ (NSFetchRequest<Conversation *> *)fetchRequest {
// body
return nil;
}
#end
And last question: Are you sure there exists no other class extension with the same name in your project? CoreData might also have created them itself.
Please have a look in your xCode Project like this:

Found the solution to my problem in this answer. I just had to remove the .m files from the Compile Sources.

Related

Cannot call Swift method in Objective-C .m file

I have big problem with one part of my code.
I have simple function in my ViewController.swift file (on end):
ViewController.swift
#objc class Constant: NSObject {
override init() {}
#objc class func parseApplicationId() -> String { return "lol" }
#objc func printSome() { print("teeeeest") }
}
Now I have one pod (charts graphic) what was written in Objective-C. So I created Bridging file called:
myprojectname-Swift.h
#import "EColumnChartViewController.h"
In header file of Objective-C file:
HEADER.h
#import <UIKit/UIKit.h>
#import "EColumnChart.h"
#import "myprojectname-Swift.h"
#class Constant;
#interface Constant : NSObject
-(void)printSome;
#end
and in my FILE.m I have this:
#import "myprojectname-Swift.h"
- (void)viewDidLoad
{
[super viewDidLoad];
Constant * sis = [[Constant alloc] init];
[sis printSome];
}
My problem is:
When I build a project, Xcode call me error:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_Constant", referenced from:
objc-class-ref in EColumnChartViewController.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
What I trying to make solution:
New Bridging file
Switching off some parts of Build Settings
#implementation Constant -> Thread 1 error
I just want to call Swift function into Objective-C file (easy call print console). Thanks for every idea.
Last words: I've checked so many posts on Stackoverflow.
Duplicate classes
The main issue appears to be that you have created two classes named Constant: one in Swift and another in Objective-C. You can only have one class with a given name.
This #objc class Constant: NSObject and #interface Constant : NSObject both create the same class. Rename one of these.
Possibly incorrect bridging
The Swift bridging header is special. You can't just create a header file and expect that to work in Swift.
Ensure that the bridging header is properly set in Xcode.
Click the project at the top to open the config screen
Search for SWIFT_OBJC_BRIDGING_HEADER
Make sure the value points to your bridging header. For example: myprojectname/myprojectname-Bridging-Header.h
In the bridging header file, put the Objective-C import for the class that you want Swift to be able to use: #import "EColumnChartViewController.h"
Other Issues
In HEADER.h:
remove #class Constant;. This is doing nothing for you.
Move the #import for EColumnChart.h and myprojectname-Swift.h into the .m file only.
The FILE.m should have an #import HEADER.h. Every .m must import it's .h!
On the line #objc class Constant: NSObject, remove the #objc... it's obviously Objective-C because it extends NSObject.
As some commenters have stated, you have provided code with an astonishing number of problems. You should really take the time to learn Objective-C and/or Swift first. Start by watching some of the free WWDC videos or Googling for intro to iOS.
Make step by step above
You use #objcMembers above declare class in swift file.
Import <"Your_Project">-Swift.h in .m file.
objcMembers
class ObjectA: NSObject {
.....
}

Objective- C - duplicate interface definition for class

When I build my app in Xcode, I have this error:
Duplicate interface definition for class BFTask
I followed some tutorials and answers, on this site, about headers and I modified it, but nothing has changed. The same error persist during build.
in BFtask.h file:
#import<foundation/Foundation.h>
#class BFTask;
.
.
.
#interface BFTask:NSObject
...
in BFTaskCompletionSource.h file:
#class BFTask;
#interface BFTaskCompletionSource;
in BFTaskCompletionSource.m file:
#import<foundation/Foundation.h>
#import "BFTask.h"
#interface BFTaskCompletionSource()
...
#interface BFTask(BFTaskCompletionSource)
You haven't shown us the BFTask.m file. I suspect you will find you have an #interface BFTask at the top of that file. If you want to declare any additions to a class in the .m file, you have to have an #interface BFTask () with the parentheses...
I have tested this and if you leave out the parentheses, the specific wording you will get for the error is, "Duplicate interface definition for class 'BFTask'"... exactly as you have reported.
If this is correct, you have two possible ways to fix this in the BFTask.m file:
If there is nothing between the #interface BFTask and the following #end, just delete them both.
If there are additional methods or properties declared there, just add a pair of parentheses after the BFTask to have #interface BFTask ().

error in ACAccount.h in Simulator-iOS 7.1

I'm trying to build and test an app with the xcode simulator, but during the building I get errors in ACAccount.h, ACAccountType.h, etc.
The "strange thing" (at least for me as i'm completely new in using xcode) is that if I click on the .h files with errors they do not appear under the project code but under
Simulator - iOS 7.1-> Frameworks -> Accounts -> ACAccount.h
which is unmodifiable.
Examples of the errors are:
line:
#class ACAccountType,ACAccount Credential; --> Illegal interface qualifier
ACCOUNTS_CLASS_AVAILABLE(NA, 5_0)
#interface ACAccount : NSObject -->Objective-C declarations may only appear in global scope
If the .h are predefined files.. How can I solve these errors?
Many thanks in advance!
Generally when you encounter items like the 'illegal interface qualifier' in system provided headers it indicates that you've placed the #import statement within an #interface block, like:
#interface foo ()
#import <Accounts/ACAccount.h>
#end
This generates errors about the content in the file being imported (e.g. your illegal interface qualifier error), while the actual issue is that putting #import statements within an #interface block is invalid.
You should put #import statements together at the top of the file, outside of any #interface or #implementation blocks.
If you put it into the #implementation section, the error becomes:
error: Objective-C declarations may only appear in global scope

XCode 5 - Undefined symbols for architecture armv7:

I am getting this error for a single class from a static library, which I have compiled myself. It has all been working fine and I wanted to add another class as a simple data transfer object called PPClientData.
The error is:
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_PPClientData", reference from: objc-class-ref in
CPPIntegrationDelegate.o
The relevant file is included in the library compile targets and I have used otool -d on the (fat) library and it shows
libPPIntegration.a(PPClientData.o) (architecture armv7):
(__DATA,--data) section
The header for the class (PPClientData.h), which is included in the app is like this:
#import <Foundation/Foundation.h>
#interface PPClientData : NSObject
#property(nonatomic, strong) NSString* clientId;
// 3 others identical to the above with different names
#end
and the .m file which should be compiled into the library looks like this:
#import "PPClientData.h"
#implementation PPClientData
#synthesize clientId;
//Synthesize others
-(id)init {
self = [super init];
return self;
}
#end
It is consumed in a single class in the app as follows. If this one function that consumes it is commented out, the linker error goes away (it links to other classes in the library) but with this in, it fails. This is a delegate function for the library.
#import "CPPIntegrationDelegate.h"
#import "PPClientData.h"
#implementation CPPIntegrationDelegate
// Various other functions that work fine
-(PPClientData*)clientData:(PPIntegration*)integration {
PPClientData* dict = [[PPClientData alloc]init]; // This is the line that causes the linker error
dict.clientId = #"whatever";
// set other properties of dict
return dict;
}
I understand what the linker is trying to do and what the error suggests but I don't see what I've missed. Can anyone help?
If you are on Xcode 5.1, try to remove arm64 from Valid Architectures (under Build Settings) and also change the Architectures from "Standard architectures" to just armv7 and armv7s. This might be relevant to you: how to stop xcode5.1 building for 64bit
Well, it wasn't the architectures causing the problem but in some way, xcode or whatever had been confused by the order of the forward declaration of the class I was using and then the definition itself. Initially, the broken code was something like:
BrokenClass.h
// Definitions etc.
GoodClass.h
#class BrokenClass;
- (BrokenClass*)someMethod:(SomeType*) param;
GoodClass.m
#import "BrokenClass.h"
- (BrokenClass*)someMethod:(SomeType*) param
{
}
Which was included into my App by including GoodClass.h into a header file, which forward declared BrokenClass and then included BrokenClass.h into an m file which should have completed the definition, where the class was used.
Anyway, to fix it, I changed the GoodClass code to:
GoodClass.h
#import "BrokenClass.h"
- (BrokenClass*)someMethod:(SomeType*) param;
Removed the #import in the m file and then only included the one GoodClass.h into my app (which brought in the BrokenClass).
Whether this is a bug somehow or more likely, I had too many forward declarations etc. I'm not sure.

Multiple ViewController inheritance causes Apple Mach-O Linker Error

I'm setting up a base view controller called "BHAccountBaseViewController" and two other views that inherit from some basic functionality from the base controller.
"BHAccountBaseViewController" Inherits from "UIViewController"
"BHAccountViewController" (implements UITextFieldDelegate) and Inherits from "BHAccountBaseViewController"
Lastly I have one recently created class that I called "BHCreateProfileViewController" every time that I just simply include #import directive to "BHAccountBaseViewController" to inherit from this class Xcode fails to compile due to APPLE MACH-O LINKER ERROR!
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Thoughts? these are my three header files
BHAccountBaseViewController
#import <UIKit/UIKit.h>
#import "BHFileManager.h"
#interface BHAccountBaseViewController : UIViewController
#end
BHAccountViewController
#import "BHAccountBaseViewController.h"
#interface BHAccountViewController : BHAccountBaseViewController<UITextFieldDelegate>
#end
BHCreateProfileViewController
#import "BHAccountBaseViewController.m"
#interface BHCreateProfileViewController : UIViewController <UITextFieldDelegate>
#property (strong, nonatomic) id user;
#end
if I comment out the import on the last file the linker error goes a way! but I want to be able to inherit from my base clase ... thoughts?
Help would be much appreciated!
In implementation of BHCreateProfileViewController given above, I found the code looks like getting wrong at first line. What about fixing it as following:
#import "BHAccountBaseViewController.m"
to
#import "BHAccountBaseViewController.h"
and I wonder why BHCreateProfileViewController comes to inherit from UIViewController not BHAccountBaseViewController. Could you explain that?
This might be due to the retain cycle deadlock problem. You have to use forward class declaration for this i.e you can try #Class instead of #import. Please refer to these limks :
Objective-C: Forward Class Declaration
#class vs. #import
These might help.
In the compilation time your compiler would actually look for your interface files instead of implementation file.Compiler does not bother even if .m file is not available. So while importing you are supposed to import .h instead .m.

Resources