passing functions address to the function pointer in Objective C - objective-c

I need to pass a address of the function to a function pointer.Below is the code what i'm
trying to accomplish it.I'm sure that i'm mistaking somewhere so that i'm getting a
runtime exception.How to pass the address of a function to a function pointer.Am i
missing something in this code.
RS232Msg.h
typedef RS232Msg* (*tpNewMsg)(void);
typedef struct
{
int nMessageId;
NSString* szAsciiName;
tpNewMsg pNewMessageFunc;
} stRs232Struct;
#interface RS232Msg : NSObject
{
}
#end
RS232Msg.m
#implementation RS232Msg
-(id)initWithRS232Msg:(int)uMessageId withNewMsg:(tpNewMsg)pNewMsg withAsciiName:(const char*)szAsciiName withData:(void*)pData withSize:(size_t)uDataSize
{
//stmts;
}
#end
RS232Derived.h
#interface RS232MsgRequestSession : RS232Msg{
}
+(RS232Msg*)NewMsg;
RS232Derived.m
#implementation RS232MsgRequestSession
+(id)FromMsg:(RS232Msg*)pMsg
{
pMsg = [RS232MsgRequestSession alloc];
return pMsg;
}
-(id)init
{
if (self = [super initWithRS232Msg:[RS232MsgRequestSession getID] withNewMsg:[RS232MsgRequestSession NewMsg] withAsciiName:NULL withData:&st withSize:sizeof(st)]) {
}
return self;
}
#end
A run time exception happens when i tried to pass the address of the function
withNewMsg:
[RS232MsgRequestSession NewMsg]
to the function pointer pNewMsg() in the initWithRS232Msg
method.

[RS232MsgRequestSession NewMsg] doesn't get you the address of the method. The expression is evaluated and the result object is passed as the argument. While there is a way to access the implementation of a method directly (read this for details), there might be an easier way to achieve what you want.
Selector based approach
Instead of what you're doing right now, you can consider doing something like this,
- (id) initWithTarget:(id)aTarget action:(SEL)aSelector ... {
// save these two for later reference.
}
and later,
if ( [target respondsToSelector:theSelector] ) {
result = [target performSelector:theSelector];
}
This way you can achieve what you want.
Blocks based approach
Truth be told, Blocks are turning out to be the best addition to Objective-C.
Change the typedef to typedef RS232Msg* (^tpNewMsg)(void);
Now the init method would become,
-(id)init
{
self = [super initWithR232Msg:[RS232MsgRequestSession getID]
withNewMsg:^{
return [RS232MsgRequestSession NewMsg];
}
withAsciiName:NULL
withData:&st
withSize:sizeof(st)]
if ( self ) {
// do stuff
}
return self;
}
#end

Related

Nonnull violation detection in Objective-C

I have some code like this where I declare an object with nonnull properties
#interface HelloObject : NSObject
#property (nonatomic,strong,nonnull) NSString *foo;
#property (nonatomic,strong,nonnull) NSString *bar;
-(instancetype _Nullable)initWithJson:(nonnull NSDictionary*)json;
#end
and then to initialize the object from the JSON I make use this code:
-(instancetype _Nullable)initWithJson:(nonnull NSDictionary*)json
{
if( (self = [super init]) ) {
_bar = json[#"bar"];
_foo = json[#"foo"];
}
return self;
}
The server may have sent me malformed JSON. For example, the "foo" field might be missing. It would be easy enough to check for nil and return nil, but I have a lot of this code and it would be inelegant and error prone.
Is there a easy and elegant way to check to see if an object violates its nonnull declarations at runtime? For example, I don't want to write code like this:
barX = json[#"bar"];
if (barX) {
_bar = barX;
} else {
return nil;
}
That's ugly and boilerplate (and therefore prone to error). I'd much rather have something like:
if (![self ValidForNonNulls]) {
return nil;
}
but I can't think of a way to write ValidForNonNulls for a general object.
I don't think that trying to work around the need to test for nil is practical in Objective-C.
If I were having to verify many such incoming terms, and I needed to check them for validity or return nil, then I would rewrite my initWithJson method to check, with a category to keep the code clean and readable.
- (instancetype _Nullable)initWithJSON:(nonnull NSDictionary *)json
{
if ( (self = [super init]) ) {
if ( ![json hasValuesForKeys:#[#"foo", #"bar"]] ) {
//Consider logging this as an error
return nil;
}
_bar = json[#"bar"];
_foo = json[#"foo"];
}
return self;
}
...
#interface NSDictionary (hasValuesForKeys)
- (BOOL)hasValuesForKeys:(NSArray *)keys;
#end
#implementation
- (BOOL)hasValuesForKeys:(NSArray *)keys
{
for (NSString *key in keys) {
if ( !self[key] || [self[key] isEqual:[NSNull null]] ) {
return NO;
}
}
return YES;
}
#end
You could make more specific tests for each value if you need to validate whether they are NSNumber for example.

Obj-C Variable Stack Type

As a foray into new programming languages, I build well known data structures to familiarize myself with the syntax and the basic ins & outs of the language. In this case, I examine the stack in Objective-C. From Apple's Working with Objects we read about the keyword 'id'
...This is a special keyword used in Objective-C to mean “some kind of object.” It is a pointer to an object, like (NSObject *), but is special in that it doesn’t use an asterisk.
By using the keyword 'id', it seems possible to create a stack data structure that holds differing types of Obj-C objects; however, I am not sure if this as intended. Is it better to create the various class methods for each potential data type rather than attempting a generic method and make sure each stack adheres to a single Object type?. Here is what I have so far
XYZNode.h
#import <Foundation/Foundation.h>
#interface XYZNode : NSObject
#property id value;
#property XYZNode *next;
-(instancetype)initWithValue:(id)aValue next:(XYZNode *)aNext;
-(instancetype)init;
// Class factory methods should always start with the name of
// the class (without the prefix) that they create, with the
// exception of subclasses of classes with existing factory methods.
+(XYZNode *)nodeWithValue:(id)aValue nextNode:(XYZNode *)aNext;
#end
XYZNode.m
#import "XYZNode.h"
#implementation XYZNode
-(instancetype)initWithValue:(id)aValue next:(XYZNode *)aNext {
if (self = [super init]) {
_value = aValue;
_next = aNext;
} return self;
}
-(instancetype)init {
return [self initWithValue:nil next:nil];
}
+(XYZNode *)nodeWithValue:(id)aValue nextNode:(XYZNode *)aNext {
return [[self alloc] initWithValue:aValue next:aNext];
}
#end
XYZStack.h
#import <Foundation/Foundation.h>
#interface XYZStack : NSObject
-(void)pushValue:(id)aValue;
-(id)popValue;
-(BOOL)isEmpty;
-(instancetype)init;
-(instancetype)initWithValue:(id)aValue;
+(XYZStack *)stackWithValue:(id)aValue;
#end
XYZStack.m
#import "XYZStack.h"
#import "XYZNode.h"
// The extension hides how the values are stored
#interface XYZStack ()
#property XYZNode *lastNodeAdded;
#end
#implementation XYZStack
// Default initializer
-(instancetype)initWithValue:(id)aValue {
if (self = [super init]) {
_lastNodeAdded = nil;
}
if (aValue) {
[self pushValue:aValue];
}
return self;
}
// Call default initializer
-(instancetype)init{
return [self initWithValue:nil];
}
-(BOOL)isEmpty{
return ([self lastNodeAdded] == nil);
}
-(void)pushValue:(id)aValue {
[self setLastNodeAdded:[XYZNode nodeWithValue:aValue nextNode:[self lastNodeAdded]]];
}
-(id)popValue {
id temp = [[self lastNodeAdded] value];
[self setLastNodeAdded:[[self lastNodeAdded] next]];
return temp;
}
+(XYZStack *)stackWithValue:(id)aValue {
return [[self alloc] initWithValue:aValue];
}
#end
Any comments would be appreciated.

"Converting" a function pointer to a block in objective-C

I'm doing some Interop from Mono C# to Obj-C and ran into this problem.
The C# code needs to pass a callback - which it does with a function pointer.
I can get the function pointer from the Obj-C side and call it and everything works.
But I now need to give that function pointer as a callback to third party API which works with blocks as a callback.
I want the third party to call the C# function - so in a way i'm trying to either convert the function pointer to a block so the third party can run it, or make some sort of a bridge - create my own block that runs that function pointer and give it to the third party. I can't seem to find a way to do that - how would I generate a block with info of which function to run and then give it to the third party.
Maybe there's another option for me?
Edit: Putting the function in a global variable might work but I want to be able to have a multitude of those as the third party API is asynchronous and I don't want it calling the wrong callback.
Code I tried :
typedef void (*DummyAction)(char * result);
typedef void (^DummyBlock)(char * result);
#interface FunctionToBlock : NSObject
{
DummyAction function;
DummyBlock block;
}
- (id) initWithFunction: (DummyAction) func;
- (DummyBlock) block;
#end
#implementation FunctionToBlock : NSObject
- (id) initWithFunction: (DummyAction) func {
if (self = [super init]) {
function = func;
block = ^(char * result) {
function(result);
};
}
return self;
}
- (DummyBlock) block {
return block;
}
#end
And then I run this with
void RegisterCallback( char * text, DummyAction callback)
{
FunctionToBlock *funcToBlock = [[FunctionToBlock alloc] initWithFunction : callback];
funcToBlock.block(text);
}
And it fails with BAD_ACCESS. Maybe i'm doing something wrong as i'm not very proficient with Obj-C yet. I can confirm that the callback is ok if run directly and that the block is being called but it fails on the function(result) line.
why not just have a simple function
typedef void (*DummyAction)(char * result);
typedef void (^DummyBlock)(char * result);
DummyBlock functionToBlock(DummyAction func) {
return [[^(char * result) {
func(result);
} copy] autorelease];
}
What about
void (*myFunc)(int x); // ... your function pointer
void (^myBlock)(int) = ^(int x) {
myFunc(x);
};
Then myBlock is a block that captures the value of the function pointer and calls the function when the block is executed.
ADDED: My suggestion, based on your code, using a #property (and assuming that you compile with ARC):
FunctionToBlock.h:
typedef void (*DummyAction)(char * result);
typedef void (^DummyBlock)(char * result);
#interface FunctionToBlock : NSObject
{
DummyAction function; // Not really needed.
}
- (id) initWithFunction: (DummyAction) func;
#property(copy, nonatomic) DummyBlock block; // "copy" is important here!
#end
FunctionToBlock.m:
#import "FunctionToBlock.h"
#implementation FunctionToBlock : NSObject
#synthesize block = _block; // Can be ommitted if you use Xcode 4.4 or later.
- (id) initWithFunction: (DummyAction) func
{
if (self = [super init]) {
function = func; // Not really needed.
self.block = ^(char * result) {
func(result); // Use "func", not "self->function", to avoid retain cycle.
};
}
return self;
}
A block is under the hood a pointer to a local data structure. A block becomes invalid as soon as you leave the scope where it was declared. The scope is the if-statement within init; as soon as you leave that, the block is invalid.
You are breaking coding conventions here in a bad way. First, instance variables should start with an underscore, so that everyone sees what you are doing. Better to use properties without declaring instance variables at all. And every block property should be declared as "copy". If you do that, everything is fine.

Objective-C, enumerators and custom setters - How to make it work?

I have an Application Delegate class with a enumeration which looks like this:
typedef enum {
Online = 3500,
DoNotDisturb = 9500,
Offline = 18500,
Away = 15500,
Busy = 6500,
BeRightBack = 12500
} status;
Additionally I have a property to set a value from the enumerator in my interface file:
#interface MyAppDelegate : NSObject <UIApplicationDelegate> {
status userStatus;
}
#property (nonatomic, setter=setStatus) status userStatus;
#end
Finally I have the following message in my implementation file:
#implementation Communicator2AppDelegate
- (void)setStatus:(status)_userStatus {
if ([NSThread isMainThread]) {
// some stuff happens here ...
} else {
[self performSelectorOnMainThread:#selector(setStatus:) withObject:_userStatus waitUntilDone:NO];
}
}
My issue is the following: the performSelectorOnMainThread message isn't working because it doesn't accept '_userStatus' as a value. My guess is the message assumes it's an enum, not a real value. I get the following error message upon compilation: "Incompatible type for argument 2 of 'performSelectorOnMainThread:withObject:waitUntilDone.'"
Does anyone have any idea on how to make this work?
You need to pass an object value to this method and enum (that is int) is scalar value. To achieve what you need you must wrap your integer to obj-c object (e.g. NSNumber):
- (void)setStatus:(status)_userStatus {
if ([NSThread isMainThread]) {
// some stuff happens here ...
} else {
[self performSelectorOnMainThread:#selector(setStatus:) withObject:[NSNumber numberWithInt:_userStatus] waitUntilDone:NO];
}
}

In Objective-C, can I declare #property on a c-array of floats?

thing.h
#interface Thing : NSObject
{
float stuff[30];
}
#property float stuff;
#end
thing.m
#implementation Thing
#synthesize stuff;
#end
I get error: type of property 'stuff' does not match type of ivar 'stuff'
I don't want to use an NSArray because I'd have to make the floats into NSNumbers (right?) and that's a pain to do math with.
Update: I've noticed similar answers had guesses and trial answers. While I appreciate the attempts by non-Objective-C folks, I'm hoping for a definitive answer whether it's possible or not.
OK, I have compiled up the following code at it works as expected.
FloatHolder.h
#interface FloatHolder : NSObject {
int _count;
float* _values;
}
- (id) initWithCount:(int)count;
// possibly look into this for making access shorter
// http://vgable.com/blog/2009/05/15/concise-nsdictionary-and-nsarray-lookup/
- (float)getValueAtIndex:(int)index;
- (void)setValue:(float)value atIndex:(int)index;
#property(readonly) int count;
#property(readonly) float* values; // allows direct unsafe access to the values
#end
FloatHolder.m
#import "FloatHolder.h"
#implementation FloatHolder
#synthesize count = _count;
#synthesize values = _values;
- (id) initWithCount:(int)count {
self = [super init];
if (self != nil) {
_count = count;
_values = malloc(sizeof(float)*count);
}
return self;
}
- (void) dealloc
{
free(_values);
[super dealloc];
}
- (float)getValueAtIndex:(int)index {
if(index<0 || index>=_count) {
#throw [NSException exceptionWithName: #"Exception" reason: #"Index out of bounds" userInfo: nil];
}
return _values[index];
}
- (void)setValue:(float)value atIndex:(int)index {
if(index<0 || index>=_count) {
#throw [NSException exceptionWithName: #"Exception" reason: #"Index out of bounds" userInfo: nil];
}
_values[index] = value;
}
#end
then in your other application code you can do something like the following:
** FloatTestCode.h **
#import <Cocoa/Cocoa.h>
#import "FloatHolder.h"
#interface FloatTestCode : NSObject {
FloatHolder* holder;
}
- (void) doIt:(id)sender;
#end
** FloatTestCode.m **
#import "FloatTestCode.h"
#implementation FloatTestCode
- (id) init
{
self = [super init];
if (self != nil) {
holder = [[[FloatHolder alloc] initWithCount: 10] retain];
}
return self;
}
- (void) dealloc
{
[holder release];
[super dealloc];
}
- (void) doIt:(id)sender {
holder.values[1] = 10;
}
The type of the property must match the type of the instance variable it will be stored in, so you could do something like
#interface Thing : NSObject
{
float stuff[30];
}
#property float[30] stuff;
#end
and it should work. I wouldn't recommend it though.
I'm guessing you're looking for something like indexed properties from Delphi. The closest you'll get is something like the following.
#interface Thing : NSObject
{
float stuff[30];
}
- (void) setStuff:(float)value atIndex:(int)index;
- (float) getStuffAtIndex:(int)index;
#end
You can't do it the way you want to do it. You can jump through some hoops and get something similar, e.g. using Daniel's solution, but it's not quite the same thing. The reason you can't do it is that arrays are not lvalues in C. An lvalue is something that can appear on the left-hand side of an assignment. The following code is invalid C:
float stuff1[30], stuff2[30];
stuff1 = stuff2; // ERROR: arrays are not lvalues
As a consequence, you can't declare properties whose types are not lvalues.
Daniel's FloatHolder answer has a major bug (edit: he's now fixed it). It only allocates memory for one float and not for the whole array.
The line:
_values = malloc(sizeof(float));
Should be:
_values = malloc(sizeof(float) * count);
Otherwise it seems to be a good answer. Sorry couldn't work out how to reply directly. (edit: I didn't have the necessary privilege on stackoverflow then.)
Even if you could get that to compile, it wouldn't behave well. 'stuff' would return a float*, and the client would have no idea how long the array way; 'setStuff:' would just change the pointer, and you'd either be pointing to stack-allocated data that would vanish out from under you or heap-allocated data that would leak because it wouldn't know to free it.
I'm not well-versed in Objective-C 2.0, but I'm guessing that the issue might be caused by the fact that a C array is essentially just a pointer to the first element of the array, meaning that the type of float stuff[30] is actually float *, not merely a float.