2011-04-06 34 views
0

所以我想在Objective-C中得到一个回调设置。我使用C++,所以我一直以错误的方式击中这些东西。我找到了这个答案,并一直试图以同样的方式建模我的代码。Objective-C回调改变参数值

How to perform Callbacks in Objective-C

然而,当我在“LocationActivated”功能,使XCOORD和YCOORD似乎完全错误的价值观。

delegate.mm

- (void)Initialize { 
    [mWorldObj RegisterActivateDelegate: self]; 
} 

-(void) LocationActivated :(float)xCoord :(float)yCoord { 

    int a; 
    a++; 
    pLocation.center = CGPointMake(xCoord, yCoord); 
} 

delegate.h

-(void) LocationActivated :(float)xCoord :(float)yCoord; 

world.h在world.mm

id mActivateDelegate; 

委托调用

 float msgarr[2]; 
     msgarr[0] = (float)((camera.VideoWidth() * 0.5f) + projX) + curLoc->mPopOffsetX; 
     msgarr[1] = (float)((camera.VideoHeight() * 0.5f) - projY) + curLoc->mPopOffsetY; 
     if(mActivateDelegate != null) { 

      [mActivateDelegate LocationActivated :msgarr[0] :msgarr[1]]; 
     } 

当调用msgarg [0]和[1]是完全有效的值时,〜(200,200)。但是在回调中,这些值现在完全不同了。我倾倒了双方的记忆,并没有看到任何共同点,所以我最好的猜测是我正在做的功能调用完全错误。

我还在[mActivateDelegate LocationActivated]行上发出警告,提示'Location Activated may not repsond',这是有道理的,因为只要编译器知道mActiveDelegate是'id'类型的。

任何想法我做错了什么?更好的方法来解决这个问题

编辑:从delegate.mm

- (void)RegisterActivateDelegate :(id) delegate { 

    mActivateDelegate = delegate; 
} 
+1

我意识到这不是一个答案,但要注意这个警告。这意味着什么是错的。您应该能够在没有警告的情况下调用id类型对象上的任何已知方法。该警告可能意味着mActivateDelegate实际上并不是id类型,但在这种情况下,它可能意味着什么。 – 2011-04-06 17:50:01

回答

1

你问了一个更好的方法来做到这一点。我直接在窗口中输入这个,所以我不知道它是否编译,但这是如何处理它。使用ObjC约定命名事物。如果你不这样做,这很重要,会破坏事物。方法从小写开始。命名您的参数。

World.h

@protocol WorldDelegate; 
@interface World : NSObject 
@property (nonatomic, readwrite, assign) id<WorldDelegate> delegate; 
@end 

@protocol WorldDelegate <NSObject> 
- (void)world:(World*)world didActivateLocation:(CGPoint)aPoint; 
@end 

World.mm

@implementation World 
@synthesize delegate = delegate_; 

- (void)dealloc { 
    delegate_ = nil; 
    [super dealloc]; 
} 

... 

if ([self delegate] != nil) { 
    CGFloat x = ((camera.VideoWidth() * 0.5f) + projX) + curLoc->mPopOffsetX; 
    CGFloat y = ((camera.VideoHeight() * 0.5f) - projY) + curLoc->mPopOffsetY; 
    [[self delegate] world:self didActivateLocation:CGPointMake(x, y)]; 
} 

WorldDelegate.h

#import "World.h" 
@interface WorldDelegate : NSObject <WorldDelegate> 
@property (nonatomic, readwrite, assign) World *world; 
- (id)initWithWorld:(World*)aWorld; 
@end 

WordDelegate.mm

@interface WorldDelegate 
@synthesize world = world_; 
- (id)initWithWorld:(World*)aWorld { 
    self = [super init]; 
    [aWorld setDelegate:self]; 
    world_ = aWorld; 
    return self; 
} 

- (void)dealloc { 
    [world_ setDelegate:nil]; 
    world_ = nil; 
    [super dealloc]; 
} 

- (void)world:(World*)aWorld didActivateLocation:(CGPoint)aPoint { 
    int a; // What is all this? 
    a++; 
    pLocation.center = aPoint; 
} 
+0

感谢罗布,这工作。经过一番探索之后,我发现根是我的一系列花车。传递:msgarr [0]:msgarr [1]会失败,而传递一个Point工作得很好。还传递只是:xFloat:yFloat也似乎工作。也许嵌套[]的使其不愉快。在附注中,感谢正式协议的例子,我一直使用非正式的协议,但它似乎很危险。 – TurqMage 2011-04-06 19:10:36

0

编辑

增加注册功能,原来我真的不知道答案。我认为Objective-C方法需要命名参数,但实际上您的方法签名是有效的。但是,您应该应该使您的方法名称尽可能描述。

你应该给你的参数名称。例如,您的委托方法应该是这样的:

- (void)locationActivatedWithX:(float)xCoord andY:(float)yCoord; 

虽然it's not 100% crucial,这是很好的风格。

+0

没有。你的建议是很好的风格,但不是关键。 – 2011-04-06 17:45:17

+1

我没有低估这一点,但事实并非如此。 Objective-C将采用匿名参数。然而,这是非常好的建议来命名它们; TurqMage正在与这里的语言交流,这将导致痛苦。然而,这可能不是那么痛苦。 – 2011-04-06 17:46:58

+0

谢谢你指出这一点。我的错! – 2011-04-06 17:50:42

0

一个问题 - 不要检查== NULL。检查== nil。必须检查Objective-C对象是否为“无”,这意味着它们是有效的对象,但它们没有引用任何内容。你的委托对象是存在的,并且作为一个Objective-C类型的对象它有一些信息(比如保留计数,isa指针等),所以它不一定是NULL,但仍然可以为零,因为实际上并没有引用实际的对象。

而且,如果事情是正确的,你不会获取警告信息“‘位置激活可能不repsond’”。该编译器足够聪明抑制对ID类型的警告,如果方法声明确实存在于你所包含的接口中。既然你得到了警告,那听起来很腥 - 就像它没有看到你的界面声明或者你在那里有什么.h不太对。

你的RegisterActiveDelegate方法是什么样的?你说你做了内存转储,所以你真正想要的方法被称为听起来像。

+0

'NULL'和'nil'都会检查空引用。 – FreeAsInBeer 2011-04-06 18:02:28

+0

对于类型正确性检查nil是件好事,但nil是0,就像NULL一样。它不是一个空的物体。如果您尝试取消引用不指向真实对象的指针,则会崩溃。指向objC对象的指针仍然只是指针。 – 2011-04-06 18:06:27

+0

@Rob:我认为发送到NULL的消息被忽略了,这意味着''dealloc''空引用不会导致崩溃。 – FreeAsInBeer 2011-04-06 18:08:53