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

时间:2015-04-29 16:29:01

标签: ios objective-c iphone ipad exc-bad-access

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

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

这是我的Button类,其中“identifier”被返回给调用者:

// 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);

这是回调方法,一旦检测到触摸,就会被Button调用。这是抛出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?

2 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:1)

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