Objective-C:使用参数调用objc_msgSend时,为什么会出现EXC_BAD_ACCESS异常



我在Sprite Kit/iOS 7.0中处理自己的Button类时遇到了一些问题。一旦我尝试用"objc_msgSend"回调该方法,我就会收到以下错误:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)

这是我的Button类,其中"标识符"返回给调用者:

// Header File *.h
@property (nonatomic, readwrite, strong) NSString* identifier;
@property (nonatomic, readonly, weak) id targetTouchUpInside;
@property (nonatomic, readonly) SEL actionTouchUpInside;
// Implementation File *.m
// ... this code is in the initializer method
NSMutableString *identifier = [[NSMutableString alloc]init];
[identifier appendFormat:@"%d:%d", menuId, itemId];
[self setIdentifier:[identifier copy]];
// ... this code is called to inform the observer about an event
objc_msgSend(_targetTouchUpInside, _actionTouchUpInside, _identifier);

这是一种回调方法,一旦检测到触摸,按钮就会调用该方法。这是EXC_BAD_ACCESS异常的抛出点。"标识符"是"nil",但仅在iPad Air上,有趣的是,它在iPhone 4S上运行良好。

// ... this is the callback method in the object that instantiates the button object
- (void)itemTouchInside:(NSString*)identifier {
NSLog(@"ID CALLED: %@", identifier);
}

我观察到,当我调用"objc_msgSend"时,它也能在iPad上工作。。。

  • 不带"_identifier"参数和/或
  • 使用"int"而不是"NSString*"作为参数
  • 带有预定义的不可变NSString*identifier=@"fixed string">

但我需要像上面的代码片段中所示那样动态定义_identifier。

你知道为什么这在iPhone上有效而在iPad上无效吗?

我建议您将objc_msgSend的使用替换为以下内容:

[self.targetTouchUpInside performSelector:self.actionTouchUpInside withObject:self.identifier];

请注意属性的使用。您有属性,请使用它们。

正如其他人提到的,最好用copy而不是strong定义identifier属性。消除了一些可能的(而且很难找到的)错误。

为触摸事件创建一个协议,然后进行类型检查。你所有的问题都消失了。或者使用块。现在,目标和选择器可能指向错误类别的对象。

相关内容

最新更新