Objective-C:为什么在使用参数调用 objc_msgSend 时出现 EXC_BAD_ACCESS 异常?
Objective-C: Why do I get an EXC_BAD_ACCESS exception when calling objc_msgSend with a parameter?
我在 Sprite Kit / iOS 7.0 中处理自己的按钮 class 时遇到了一些问题。一旦我尝试使用 "objc_msgSend" 回调方法,我就会收到以下错误:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)
这是我的按钮 class,其中 "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 异常的地方。 "identifier" 是 "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”参数and/or
- 使用 "int" 而不是 "NSString*" 作为参数
- 使用预定义的不可变 NSString *identifier = @"fixed-string";
但我需要动态定义 _identifier,如上面的代码片段所示。
知道为什么这适用于 iPhone 而不是 iPad 吗?
为触摸事件创建协议,然后进行类型检查。你所有的问题都会消失。或者使用积木。现在目标和选择器可能指向错误类型的对象 类.
我建议您将 objc_msgSend
的用法替换为以下内容:
[self.targetTouchUpInside performSelector:self.actionTouchUpInside withObject:self.identifier];
还要注意属性的使用。你有属性,用它们。
正如其他人提到的,最好用 copy
定义 identifier
属性 而不是 strong
。消除了一些可能(且难以发现)的错误。
我在 Sprite Kit / iOS 7.0 中处理自己的按钮 class 时遇到了一些问题。一旦我尝试使用 "objc_msgSend" 回调方法,我就会收到以下错误:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x8)
这是我的按钮 class,其中 "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 异常的地方。 "identifier" 是 "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”参数and/or
- 使用 "int" 而不是 "NSString*" 作为参数
- 使用预定义的不可变 NSString *identifier = @"fixed-string";
但我需要动态定义 _identifier,如上面的代码片段所示。
知道为什么这适用于 iPhone 而不是 iPad 吗?
为触摸事件创建协议,然后进行类型检查。你所有的问题都会消失。或者使用积木。现在目标和选择器可能指向错误类型的对象 类.
我建议您将 objc_msgSend
的用法替换为以下内容:
[self.targetTouchUpInside performSelector:self.actionTouchUpInside withObject:self.identifier];
还要注意属性的使用。你有属性,用它们。
正如其他人提到的,最好用 copy
定义 identifier
属性 而不是 strong
。消除了一些可能(且难以发现)的错误。