In Xcode 6 with Objective-C:
When I create a Cocoa Touch Framework the project has already a unit test target.
Assuming I have the following class and unit test case in my framework:
//Framework
#interface MyClass : NSObject
- (NSString*)greetings;
#end
#implementation MyClass
- (NSString*)greetings {
return #"Hello";
}
#end
// Test class
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#import "MyClass.h"
#interface MyClassTests : XCTestCase
#end
#implementation MyClassTests
- (void)testGreetings {
MyClass *myClass = [[MyClass alloc] init];
XCTAssertTrue([[myClass greetings] isEqualToString:#"Hello"]);
}
#end
When I try to run the test I get:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_MyClass", referenced from:
objc-class-ref in MyClassTests.o
Why is the test target not finding my classes? I can't figure out what is wrong. I assume that the Xcode template would set up everything correctly.
you add this x86_64 architecture in Build setting -> Valid Architecture x86_64 and try it. It can be work.
Refer the architecture:
armv7: Used in the oldest iOS 7-supporting devices
armv7s: As used in iPhone 5 and 5C
arm64: For the 64-bit ARM processor in iPhone 5S
i386: For the 32-bit simulator
x86_64: Used in 64-bit simulator
Related
I have a huge Objective-C project which I want to split into several ones in a single WorkSpace. Initially I did it, and code compiled well, but I decided also to move one category of a big class to other project, and now linker doesn't understand the situation:
Undefined symbols for architecture x86_64:
"_OBJC_IVAR_$_MyClass.data", referenced from:
-[MyClass(Viz) someTask] in MyClass+Viz.o
d: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Briefly, my workspace looks like this:
- MyLib project:
MyClass.h
MyClass.m
MyClass+Inner.h
MyClass+Inner.m
- MyApp project:
MyClass+Viz.h
MyClass+Viz.m
MyLib is compiled into MyLib.framework which is used in MyApp. As I said, before moving MyClass+Viz to MyApp project, all the complex logic worked correctly, so there is probably no problem with projects linking. Also, I checked twice that all the files are marked correctly in Build Phases settings section.
This is the MyClass.h file:
#interface MyClass : NSObject
- (instancetype)init;
- (void)public_methods;
#end
This is the MyClass+Inner.h file:
#import "MyClass.h"
#interface MyClass ()
{
// Variables placed here
// so that only class methods can access them
SomeStruct* data;
// other fields ...
}
#end
#interface MyClass (Inner)
- (void)private_methods;
#end
And the MyClass+Viz.m file:
#import "MyClass+Viz.h"
#import "MyClass+Inner.h"
#implementation MyClass (Viz)
- (int)someTask {
return data->length;
// this or any other stuff with
// class variables from MyClass+Inner.h
// leads to "Undefined symbols" by linker
}
#end
How can I make it work, make linker see class' private variables from other project?
First, you should be using #property and not instance variables, generally.
Secondly, you would do something like this using multiple header files and class extensions.
Typcially,
MyClass.h
MyClass_Internal.h
MyClass.m
MyClass_Internal.m (Not typically used)
MyClass.m would import both headers. MyClass.h would define the public interface and MyClass_Internal.h would have a class extension to provide the private interface:
#interface MyClass()
#property(...) Thing *internalThing;
#end
My project is written in ApplescriptObjC and Objective-C.
I have an NSTabViewDelegate, which must be written in ObjC:
#import <Cocoa/Cocoa.h>
#import "MSItems.h"
#interface MSTabView : NSTabView<NSTabViewDelegate>
- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem;
#end
#implementation MSTabView
- (void)tabView:(NSTabView *)tabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem {
if ([[tabViewItem identifier] intValue] == 1) {
[MSItems myMethod];
}
}
#end
MSItems class is written in ApplescriptObjC, but I created a header file, which contains only the method I need to be called by other classes.
#import <Cocoa/Cocoa.h>
#class MSItems;
#interface MSItems : NSObject
+ (void) myMethod;
#end
In the ASObjC class i have:
script MSItems
property parent : class "NSObject"
on myMethod()
--stuff
end myMethod
end script
But the app doesn't compile and I get the error:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_MSItems", referenced from:
objc-class-ref in MSTabView.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I'm trying to port a game to iOS but I'm having a problem. I have a class called CKSprite with the following method:
- (id)initWithFile:(NSString *)fileName effect:(GLKBaseEffect *)effect
{
if ((self = [super init]))
{
//some stuff
}
return self;
}
I then have a subclass called CKPLayer (it has no other methods or properties at the moment other than what it inherits:
#property (strong) CKPlayer *player1;
But when I try to initialise it using the parent method:
self.player1 = [[CKPlayer alloc] initWithFile:#"Images/parrot.png" effect:self.effect];
I get this error:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_CKPlayer", referenced from:
objc-class-ref in CKViewController.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This is my first time trying to do anything like this so I've probably done something stupid.
Any help will be greatly appreciated.
#import "CKSprite.h"
#interface CKPlayer : CKSprite
#end
The linker is missing the implementation for the class CKPlayer. Maybe you just forgot to implement it since it has "no other methods or properties at the moment", in that case just add a file which should look like:
#import "CKPlayer.h"
#implementation CKPlayer
#end
and ld should be happy
I use this library: https://github.com/robbiehanson/CocoaAsyncSocket
There are examples for TCP on the iphone but not UDP. I think that everything should be just the same. Here is my code:
#import <UIKit/UIKit.h>
#class GCDAsyncUdpSocket;
#interface ThirdViewController : UIViewController
{
GCDAsyncUdpSocket *udpSocket;
}
.m:
#import "ThirdViewController.h"
#import "DDLog.h"
#import "DDTTYLogger.h"
#import "GCDAsyncUdpSocket.h"
static const int ddLogLevel = LOG_LEVEL_VERBOSE;
#implementation ThirdViewController
- (void)viewDidLoad
{
[DDLog addLogger:[DDTTYLogger sharedInstance]];
udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
}
But when compiling I get the errors:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_DDLog",
referenced from:
objc-class-ref in ThirdViewController.o "_OBJC_CLASS_$_DDTTYLogger",
referenced from:
objc-class-ref in ThirdViewController.o "_OBJC_CLASS_$_GCDAsyncUdpSocket",
referenced from:
objc-class-ref in ThirdViewController.o ld: symbol(s) not found for architecture i386
What is wrong? Examples from the library compiled without errors.
You have to link CFNetwork.framework or if have it you're propably working on Automatic Reference Counter, turon off ARC for GCDAsyncUdpSocket using -fno-objc-arc
(Build Phases >> Link Binary With Libraries) Add CocoaLumberjack as optional dependency.
I have a project that uses the Core Telephony framework. Recently my code stopped working on a CTCarrier category, the linker complains that it can’t find the CTCarrier class:
Undefined symbols:
"_OBJC_CLASS_$_CTCarrier", referenced from:
l_OBJC_$_CATEGORY_CTCarrier_$_Foo in CTTests.o
ld: symbol(s) not found
This is a sample code that triggers the error above:
#import <CoreTelephony/CTCarrier.h>
#interface CTCarrier (Foo)
- (void) doFoo;
#end
#implementation CTCarrier (Foo)
- (void) doFoo {}
#end
If I change the category to class extension, the code suddenly builds:
#import <CoreTelephony/CTCarrier.h>
#interface CTCarrier ()
- (void) doFoo;
#end
#implementation CTCarrier
- (void) doFoo {}
#end
What’s going on? Sample code on GitHub.
There is a bug in 4.2 that doesn't allow the direct creation of a CTCarrier object, the proper way to access CTCarrier is via the CTTelephonyNetworkInfo object like so:
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
CTTelephonyNetworkInfo *telephony = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier *carrier = telephony.subscriberCellularProvider;
[telephony release];
In the first example you don't really are implementing CTCarrier class but only add a method to it. The categories provide a way to add methods to an already defined implementation.