所以我想在Objective-C中设置一个回调设置。我习惯使用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
id mActivateDelegate;
在world.mm中委派电话
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]行上收到警告,说“位置已激活可能不会重新启动”这是有意义的,因为只要编译器知道mActiveDelegate属于'id'类型。
知道我做错了什么吗?更好的方法来解决这个问题?
编辑:
从delegate.mm添加注册功能
- (void)RegisterActivateDelegate :(id) delegate {
mActivateDelegate = delegate;
}
答案 0 :(得分: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;
}
答案 1 :(得分:0)
编辑嗯,事实证明我实际上并不知道答案。我认为Objective-C方法需要命名参数,但事实上你的方法签名是有效的。但是,您应该使您的方法名称尽可能具有描述性。
您应该提供参数名称。例如,您的委托方法应如下所示:
- (void)locationActivatedWithX:(float)xCoord andY:(float)yCoord;
虽然it's not 100% crucial,但它的风格很好。
答案 2 :(得分:0)
一个问题 - 请勿检查== NULL。检查==无。必须针对“nil”检查Objective-C对象,这意味着它们是有效对象,但它们不引用任何内容。您的委托对象存在,并且作为objective-c类型对象,它具有一些信息(如保留计数,isa指针等),因此它不一定是NULL,但仍然可以是nil,因为实际上并不引用真实对象。
此外,如果事情是正确的,你将不会得到警告消息“'位置已激活可能不会重复'”...编译器足够聪明,可以在上抑制这些警告id 类型,如果方法声明确实存在于您包含的接口中。既然你收到了警告,那听起来很可疑 - 就像要么没有看到你的界面声明,要么就是你所拥有的.h不太正确。
您的RegisterActiveDelegate方法是什么样的?你说你做了一次内存转储,所以你真正想要的方法被称为听起来像。