我在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
属性。消除了一些可能的(而且很难找到的)错误。
为触摸事件创建一个协议,然后进行类型检查。你所有的问题都消失了。或者使用块。现在,目标和选择器可能指向错误类别的对象。