передача адреса функции к указателю функции в Objective C - PullRequest
0 голосов
/ 21 мая 2011

Мне нужно передать адрес функции указателю на функцию. Ниже приведен код, который я пытаюсь выполнить. Я уверен, что где-то ошибаюсь, так что получаю исключение во время выполнения.Как передать адрес функции указателю на функцию. Я что-то пропустил в этом коде.

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

Исключение времени выполнения происходит, когда я пытаюсь передать адрес функции

withNewMsg:
[RS232MsgRequestSession NewMsg]

указатель на функцию pNewMsg () в методе initWithRS232Msg.

1 Ответ

1 голос
/ 21 мая 2011

[RS232MsgRequestSession NewMsg] не дает вам адрес метода. Выражение вычисляется и объект результата передается в качестве аргумента. Хотя существует способ прямого доступа к реализации метода (подробнее см. this ), может быть более простой способ добиться того, чего вы хотите.

Подход на основе селектора

Вместо того, что вы делаете сейчас, вы можете подумать о том, чтобы сделать что-то вроде этого,

- (id) initWithTarget:(id)aTarget action:(SEL)aSelector ... {
    // save these two for later reference.
}

и позже

if ( [target respondsToSelector:theSelector] ) {
    result = [target performSelector:theSelector];
}

Таким образом, вы можете достичь того, что вы хотите.

Блочный подход

По правде говоря, блоки оказываются лучшим дополнением к Objective-C.

Измените typedef на typedef RS232Msg* (^tpNewMsg)(void);

Теперь метод init станет

-(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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...