Returning CGPoint from a Method in Objective-C - objective-c

I have the following code:
#import <Foundation/Foundation.h>
#interface BBUtils : NSObject
{
}
-(CGPoint ) randomPoints;
#end
For some reason it complains on the randomPoints method saying Expected a Type? Why?

This could happen if CoreGraphics is not available. Then you'll need to link it explicitly:

Add proper import in your header to expose structs declared by CoreGraphics:
#import <CoreGraphics/CoreGraphics.h>

Related

Expose a constant variable from Objective-C to Swift

I have to do a bitwise operation that is for some reason only possible in swift so I am looking to initialize some constants with Objective-C to be used within my application.
I am not that great with objective-c yet so the only way I knew how to do this was to create a class and give it a method that returns the value but I figure that there is a more efficient value.
There must be a more succinct way to achieve this. Currently I am doing the following:
Header:
#import <Foundation/Foundation.h>
#include <simd/simd.h>
#import <MetalKit/MetalKit.h>
#import <Metal/Metal.h>
#interface Bridge:NSObject
#property NSString *url;
- (MTLTextureUsage)readAndWrite;
#end
Implementation:
#import "MPS-Bridging-Header.h"
#implementation Bridge
- (MTLTextureUsage)readAndWrite {
return MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget | MTLTextureUsageShaderWrite;
}
#end
Swift Usage:
let bridge = Bridge()
Texture.usage = bridge.readAndWrite()
It would be great if this could be simplified to like
MTLTexReadAndWrite as if it were a constant or perhaps have it so that I can do Bridge().readAndWrite() so it is all on one line?
If you wanted to expose this to Swift, I'd define a class property:
// Bridge.h
#import Foundation;
#import Metal;
#interface Bridge : NSObject
#property (class, nonatomic, readonly) MTLTextureUsage readAndWrite;
#end
And
// Bridge.m
#import "Bridge.h"
#implementation Bridge
+ (MTLTextureUsage)readAndWrite {
return MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget | MTLTextureUsageShaderWrite;
}
#end
And you could then use it like so:
let readAndWrite = Bridge.readAndWrite
But I wonder why you don't just define this constant in Swift:
let readAndWrite: MTLTextureUsage = [.shaderRead, .renderTarget, .shaderWrite]
If you need the same constant in both Objective-C and Swift, use the above bridging pattern, but if you only need it in Swift, then I'd just define it there and eliminate Bridge altogether.

How do I properly wrtite this method out to get rid of the "missing #end" error?

#import <Foundation/Foundation.h>
#import "SuperHero.h"
'missing #end'
#implementation Superhero : NSObject
-(int)Fight:(int)enemyStamina{
int resultingStamina = enemyStamina - 5;
return resultingStamina;
}
#end
This is valid code (syntax). Without header code I can't say more, but probably You miss #end in header file. Also, try to clean and rebuild your project.
Also, as kambala mentioned, specify inheritance with #interface directive.
Inheritance is specified only in the #interface section. So remove the : NSObject part in your code and you'll be fine.

#import in #import? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I have references between two classes in Objective-C?
Objective-C #import loop
I'm getting a couple errors in my code and I'm not sure but I think its because I'm #importing an interface inside another interface where I'm #importing the other interface. If I'm confusing you I'll give you an example.
#import "OneClass.h"
#interface SecondClass : NSObject
{
OneClass * obj;
}
#import "SecondClass.h"
#interface OneClass : NSObject
{
SecondClass * obj;
}
Yes, you have a circular import. The problem here is that the second import (the one that re-imports your first header) is basically ignored by the compiler, since it thinks it's already imported that header.
The solution here is to use #class forward-declarations instead of using #imports. Not only does this solver the circular import problem, but it's a better idea anyway since it breaks unnecessary dependency chains (e.g. if I edit OneClass.h, SecondClass.h won't need to be re-processed).
To apply this here, simply remove the #import OneClass.h in SecondClass.h and replace it with #class OneClass;
In the more general case, you don't ever need to #import a header file just to declare an ivar/property/method that uses a class from that header. The #class token is sufficient. You do, however, need to #import the header file if you're inheriting from the class, or if you're referencing another non-class type declared in that header. Also remember that if you use #class in your header, you need to remember to put the actual #import into your .m file.
If you're importing a header file you need to put the full file name. In this case...
#import "SecondClass.h" instead of #import "SecondClass"
You can declare the use of a class without having to #import its associated header, like so:
// #import "SecondClass.h" // no need for this anymore
#class SecondClass;
#interface OneClass : NSObject
{
SecondClass * obj; // OK
}
When there are no physical dependencies, you should be using forward declarations to minimise your build times:
// SecondClass.h
#class OneClass;
#interface SecondClass : NSObject
{
OneClass * obj;
}
#end
// OneClass.h
#class SecondClass;
#interface OneClass : NSObject
{
SecondClass * obj;
}
#end
It also happens to fix your dependency cycle ;)

#import in objective C: Am I doing this wrong?

Sorry, couldn't find a more appropriate title.
In My code I have two classes which should know of each others existence. So I use an instance variable which points to the other class. For that to work (I guess?) the other classes headers file should be imported so it knows which methods it has and such.
Here is my code (stripped down)
MainMenuController.h:
#import <Cocoa/Cocoa.h>
#import "IRCConnection.h"
#interface MainMenuController : NSViewController {
IRCConnection *ircConnection;
}
#property (strong) IRCConnection *ircConnection;
#end
IRCConnection.h:
#import <Foundation/Foundation.h>
#import "MainMenuController.h"
#interface IRCConnection : NSObject {
MainMenuController *mainMenuController;
}
#property (strong) MainMenuController *mainMenuController;
#end
As you can see they both import each other, but this creates an error (Unknown type name 'IRCConnection') in one, and in the other Unknown type name 'MainMenuController'.
However when the connection is just one way (e.g. only MainMenuController knows about IRCConnection) and thus there is only an import statement in one of the two, it works fine.
How can I have them to know about each other? In both ways.
Hope this question makes any sense.
you could remove the import from IRCConnection.h and use a #class statement instead.
like this:
#import <Foundation/Foundation.h>
#class MainMenuController;
#interface IRCConnection : NSObject {
then add a #import "MainMenuController.h" to IRCConnection.m
In the header, use forward declaration:
#class IRCConnection;
#interface MainMenuController : NSViewController {
IRCConnection *ircConnection; // ok
}
In the source file (.m), do #import.
You cannot have circular imports. You need to break them up, or introduce some forward declarations.

Dynamically typed class generates compiler warnings on method selection

Perhaps this is the wrong way to go about this, but it seems like such a clean and workable approach that I wonder how I can make the compiler warning go away?
#interface SomeView : UIView {
NSString *stringOfsomeImportance;
RelatedClass *niftyService;
}
#property (nonatomic, copy) NSString * stringOfnoImportance;
#property (nonatomic, retain) RelatedClass *niftyService;
#implementation
-(void)someMethod;
-(void)otherMethods;
#implementation RelatedClass *pvSomeObj = [[RelatedClass alloc] initWithSender:self];
[self setNiftyService:pvSomeObj];
Now, looking at the RelatedClass implementations...
#interface RelatedClass : NSObject {
id thesender;
#property (nonatomic, retain) id thesender;
#implementation
[thesender otherMethods]; // this generates a compiler warning
// that otherMethods cannot be found
// in SomeView, though it *is* found
// and seems to execute just fine
This seems like a valid approach, so I'm left wondering why the warning?
Is there a way to better "explain" this to the compiler?
Could someone kindly share if this type of linkage is encouraged or if there is a better way to link two related, interdependent classes that need to communicate with one another?
I can't statically declare the sender object (SomeView) in RelatedClass because that seems to cause a recursion problem, as SomeView is defined with RelatedClass as a member...
Any suggestions?
You can define a protocol and say that your thesender object must conform to it:
#protocol MyProtocol
-(void)otherMethods;
#end
#interface RelatedClass : NSObject {
id<MyProtocol> thesender; // Now compiler knows that thesender must respond
// to otherMethods and won't generate warnings
}
You can send otherMethods message another way (you may need to define theSender as NSObject here):
if ([theSender respondsToSelector:#selector(otherMethods)])
[theSender performSelector:#selector(otherMethods)];
Edit: Actually you can also define thesender as SomeView* in your RelatedClass using forward class declaration:
//SomeView.h
#class RelatedClass;
#interface SomeView : UIView {
RelatedClass *niftyService;
}
// then include RelatedClass.h in SomeView.m
//RelatedView.h
#class SomeView;
#interface RelatedClass : NSObject {
SomeView* thesender;
}
// then include SomeView.h in RelatedClass.m
In your headers, you can forward declare classes that you want to use. In your implementation files, you can include the full header of those classes that you forward-declared.
For example:
SomeView.h
#import <FrameworkHeader.h>
// Here, you are saying that there is a class called RelatedClass, but it will be
// defined later.
#class RelatedClass;
#interface SomeView : UIView
{
RelatedClass *niftyService;
}
#end
SomeView.m
#import "SomeView.h"
#import "RelatedClass.h"
// By including "RelatedClass.h" you have fulfilled the forward declaration.
#implementation SomeView
// Can use "RelatedClass" methods from within here without warnings.
#end
RelatedClass.h
#import <FrameworkHeader.h>
#class SomeView;
#interface RelatedClass
{
SomeView *someView;
}
// methods
#end
RelatedClass.m
#import "RelatedClass.h"
#import "SomeView.h"
#implementation RelatedClass
// Can use "SomeView" methods from within here without warnings.
#end
id thesender = ....;
[thesender otherMethods]; // this generates a compiler warning
// that otherMethods cannot be found
// in SomeView, though it *is* found
// and seems to execute just fine
For the above to generate the warning as you describe, it is entirely because the method -otherMethods has not been declared someplace where the compiler sees the declaration before attempting to compile the call site.
That is, the declaration of the method:
- (void) otherMethods;
Must appear in a header file that is imported -- directly or indirectly -- by the implementation file compiling that particular call site or the method declaration must appear in the #implementation before the call site.