Trouble using opaque pointers in Objective C++ - iphone

The answer to this quesion explains that opaque pointers are a good way to include C++ member variables in an Objective C++ header. I'm getting compile errors when trying to follow the example. Here's the relevant code from my header, with the corresponding compiler errors shown as comments:
struct ADSR_opaque; // error: forward declaration of 'struct ADSR_opaque'
#interface LoopyPulser : NSObject{
float _pulseRate;
UInt32 tickInterval;
UInt32 step;
InMemoryAudioFile * audioFilePlayer;
ADSR_opaque* env; // error: expected specifier-qualifier-list before 'ADSR_opaque'
Pattern * pattern;
float loopLengthRatio;
float volume;
}
Is there something simple I'm doing wrong here?

I don't have any problem with the following minimal sample:
struct ADSR_opaque;
#interface LoopyPulser : NSObject {
struct ADSR_opaque* env;
}
#end
If you include the header in plain Objective-C files (not Objective-C++), you have to add struct.
Alternatively use typedefs:
struct ADSR_opaque_;
typedef struct ADSR_opaque_ ADSR_opaque;
#interface LoopyPulser : NSObject {
ADSR_opaque* env;
// ...

Related

"Ambiguous use of 'children'" when trying to use NSTreeController.arrangedObjects in Swift 3.0

I get an Ambiguous use of 'children' error in XCode 8.0/Swift 3.0 when trying to send a message to the opaque NSTreeController.arrangedObjects object.
Here is a bare playground showing the use case :
import AppKit
extension NSTreeController {
func whatever () {
let k = (self.arrangedObjects as AnyObject).children // error here
}
}
I try to use AnyObject as a bridge to the underlying ObjC object, which is supposed to be able to get through any method call, I guess.
Xcode signals that it found two candidates that could respond to a "children" message: Foundation.XMLNode and AppKit.NSTreeNode.
Of course the obvious solution (casting to NSTreeNode) is not working because arrangedObjects returns an opaque, proxy object not a real NSTreeNode
Any suggestion on how we're supposed to use NSTreeController.arrangedObjects.children in Swift 3 ?
The two candidates for the children property differ by their type:
Foundation.XMLNode:137:14: note: found this candidate
open var children: [XMLNode]? { get }
^
AppKit.NSTreeNode:12:14: note: found this candidate
open var children: [NSTreeNode]? { get }
^
You can resolve the ambiguity by casting the value of the property
to the expected type. In your case:
let k = (self.arrangedObjects as AnyObject).children as [NSTreeNode]?
Another solution: Adding an Obj-C category to NSTreeController
.h
#import <Cocoa/Cocoa.h>
#interface NSTreeController (RootNodes_m)
- (NSArray *) rootNodes;
#end
.m
#import "NSTreeController+RootNodes_m.h"
#implementation NSTreeController (RootNodes_m)
- (NSArray *) rootNodes {
NSObject * arranged = self.arrangedObjects;
if ([arranged respondsToSelector: #selector(childNodes)]) {
return [arranged performSelector:#selector(childNodes)];
}
return nil;
}
#end
Now in your code you can use it like this:
return treeController.rootNodes() as? [NSTreeNode]
I had problem with the above answer: The compiler refused to compile when "whole module optimization" was turned on. A swift extension didn't help. I'm using Xcode 8.2.1.

swift 2.0 compile error in generated swift.h file about SecCertificateRef

in our swift code somewhere there is a class with a method with this signature:
static var getCertificates : [SecCertificate] { ... }
in the generated app-swift.h this results in:
#interface TrustedCertificates : NSObject
+ (NSArray<SecCertificateRef> * __nonnull)getCertificates;
#end
and this gives the compile error:
Type argument 'SecCertificateRef' (aka 'struct __SecCertificate *') is neither an Objective-C object nor a block type
I've tried adding #import before where the .h file is included, but it doesn't solve the error.
I've also tried adding the import to the pch.h file but this also doesn't help.
Since the swift file is generated I can not start editing it there since it will be overwritten anyway.
Any idea what is missing to get it to compile?

Objective-C Constant variable not work, occurs "Property not found on object of type"

In Java, the following code is fine, no error.
class ConstantA{
public static String MY_TEST = "My Test";
}
import ConstantA;
Class TestClass{
public void test(){
System.out.println(ConstantA.MY_TEST); // it's work fine.
}
}
According to above java concept, it doesn't work on Objective-C,
in ConstantA.h file
extern NSString * const MY_TEST;
#interface ConstantA : NSObject
#end
in ConstantA.m file
NSString * const MY_TEST = #"My Test";
#implementation ConstantA
#end
in main.m file ( error occurs here)
#import "ConstantA.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
NSLog(#"%#",ConstantA.MY_TEST); // error: Property 'MY_TEST' not found on object of type 'ConstantA'
}
}
Can help me to solve this problem?
thanks so much
#import "ConstantA.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
NSLog(#"%#", MY_TEST); // error: Property 'MY_TEST' not found on object of type 'ConstantA'
}
}
Use directly the global variable, without class name:
MY_TEST and NOT ConstantA.MY_TEST.
Use NSLog(#"%#",MY_TEST);.
MY_TEST is not scoped by ConstantA in any way; it's simply a global variable. Objective-C doesn't support class-level "static variables" like you'd find in Java or C++. Classes can only have instance variables
You can sorta imitate a class variable with a global variable, but it's still just a global; it's not namespaced to the class in any way.
Put your Global string in the .h file
property (nonatomic, retain) NSString *gMyString;
In the .m file
synthetize gMyString;
It should work... I had the same problem last week !

Objective C and c++ import problem. Simple but I don't get it

I'm using cocos2d and box2d.(iPhone SDK) If I want to import box2d I add this to the top of the file #import "Box2D.h" and then I rename my class to ".mm". Now I have just a class without a ".m" file just a ".h" file.
It looks like that and if I import box2d it gives me many errors because box2d is c++ and normally i need to change it to ".mm" but i cant.
#import "Box2D.h"
// Defines individual types of messages that can be sent over the network. One type per packet.
typedef enum
{
kPacketTypeTime = 1,
kPacketTypePosition = 2,
kPacketTypeStartSignal = 3,
} EPacketTypes;
// Note: EPacketType type; must always be the first entry of every Packet struct
// The receiver will first assume the received data to be of type SBasePacket, so it can identify the actual packet by type.
typedef struct
{
EPacketTypes type;
} SBasePacket;
// the packet for transmitting a score variable
typedef struct
{
EPacketTypes type;
float time;
} STimePacket;
// packet to transmit a position
typedef struct
{
EPacketTypes type;
b2Vec2 position; //*******************************important**
float rotation;
} SPositionPacket;
// packet to transmit a start signal
typedef struct
{
EPacketTypes type;
BOOL startGame;
} SStartSignalPacket;
Why I want to do this? Look at the "**important" in my code. I want to use b2Vec2.
Thank you very much for reading.
Have a nice day :)
Try to rename header to .hh, cause compiler still treats it as Objective C

Static string variable in Objective C on iphone

How to create & access static string in iPhone (objective c)?
I declare static NSString *str = #"OldValue" in class A.
If i assign some value to this in class B as str = #"NewValue".
This value persists for all methods in class B. But if I access it in class C (after assignment in B) I am getting it as OldValue.
Am I missing something? Should i use extern in other classes?
Thanks & Regards,
Yogini
Update: As of Xcode 8, Objective-C does have class properties. Note, it's mostly syntactic sugar; these properties are not auto-synthesized, so the implementation is basically unchanged from before.
// MyClass.h
#interface MyClass : NSObject
#property( class, copy ) NSString* str;
#end
// MyClass.m
#import "MyClass.h"
#implementation MyClass
static NSString* str;
+ (NSString*) str
{
return str;
}
+ (void) setStr:(NSString*)newStr
{
if( str != newStr ) {
str = [newStr copy];
}
}
#end
// Client code
MyClass.str = #"Some String";
NSLog( #"%#", MyClass.str ); // "Some String"
See WWDC 2016 What's New in LLVM. The class property part starts at around the 5 minute mark.
Original Answer:
Objective-C doesn't have class variables, which is what I think you're looking for. You can kinda fake it with static variables, as you're doing.
I would recommend putting the static NSString in the implementation file of your class, and provide class methods to access/mutate it. Something like this:
// MyClass.h
#interface MyClass : NSObject {
}
+ (NSString*)str;
+ (void)setStr:(NSString*)newStr;
#end
// MyClass.m
#import "MyClass.h"
static NSString* str;
#implementation MyClass
+ (NSString*)str {
return str;
}
+ (void)setStr:(NSString*)newStr {
if (str != newStr) {
[str release];
str = [newStr copy];
}
}
#end
Unlike Java, where a static variable is scoped for all instances of a class, static in C means that a variable is accessible only from within the file where it is declared. It allows you to do things like declare a static variable inside a function, which sets the value only the first time through, like this.
One thing you haven't mentioned is the relationship between classes A, B, and C. If they are in an inheritance hierarchy, and you're expecting the static variable to be inherited as in Java, the method described by zpasternack will work.
If the three classes are unrelated, and you just want to access the value declared in A, then extern is a more appropriate way to go. In this case, you want to declare the variable as extern in ClassA.h, then define it in Class.m. As long as ClassB and ClassC import ClassA.h, they will be able to link against the same extern definition.
One fine point is that, instead of using extern by itself, it's more robust to use OBJC_EXPORT, which is defined in objc-api.h and handles compiling under C++ as well. Here's a code sample:
// ClassA.h
OBJC_EXPORT NSString* commonString;
...
// ClassA.m
NSString* commonString = #"OldValue";
// ClassB.m
#import "ClassA.h"
...
commonString = #"NewValue"; // Can be inside a function or method
Of course, using externed variables in this way creates an infamous, much-maligned global variable, which is fragile in that anyone can read or write it, and access is uncontrolled. This is the simple approach, and answers your question about using static vs. extern. However, as a design principle, the encapsulation provided by wrapping the variable with class methods is much safer, albeit more complex. In object-oriented languages, when the effect you're trying to achieve is that of a class-static method, encapsulation is probably the right way to go.