gpt4 book ai didi

xcode - 使用performSelector执行的方法中objc_retain崩溃

转载 作者:行者123 更新时间:2023-12-04 03:12:40 28 4
gpt4 key购买 nike

我在代码中遇到了与ARC自动插入objc_retains有关的奇怪崩溃。

我有以下两个类:

@interface MenuItem : NSObject
@property (weak, nonatomic) id target;
@property (unsafe_unretained, nonatomic) SEL action;
@property (strong, nonatomic) id object;
- (instancetype)initWIthTarget:(id)target action:(SEL)action withObject:(id)object;
- (void)performAction;
@end

@implementation MenuItem
- (void)performAction
{
if (self.target && self.action)
{
if (self.object)
{
[self.target performSelector:self.action withObject:self.object];
}
else
{
[self.target performSelector:self.action];
}
}
}
@end

@interface Widget : NSObject
- (void)someMethod:(id)sender;
@end

在某些时候,我将MenuItem实例化为:
MenuItem *item = [MenuItem alloc] initWithTarget:widget action:@selector(someMethod:) object:nil];

然后在其他地方,我在菜单项上调用 performAction:
 [item performAction];

someMethod的实现中,我崩溃了:
@implementation Widget
- (void)someMethod:(id)sender
{
// EXEC_BAD_ACCESS crash in objc_retain
}
@end

为什么会这样呢?

最佳答案

崩溃的原因是因为我使用了错误的performSelector
NSObject定义performSelector的多个版本。我要调用的是:

- (id)performSelector:(SEL)aSelector;

但是我调用的方法使用了 id参数。例如:
- (void)someMethod:(id)sender;

现在,ARC是一种很好的安全内存管理系统,它试图确保在执行方法期间正确保留参数。因此,即使我的 someMethod:为空,ARC仍会生成如下所示的代码:
- (void)someMethod:(id)sender 
{
objc_retain(sender);
objc_release(sender);
}

但是,此问题是我正在调用 performSelector:而不提供 sender参数的值。因此, sender指向堆栈上的随机垃圾。因此,当调用 objc_retain()时,应用程序崩溃了。

如果我更改:
MenuItem *item = [[MenuItem alloc] initWithTarget:widget 
action:@selector(someMethod:)
object:nil];


MenuItem *item = [[MenuItem alloc] initWithTarget:widget 
action:@selector(someMethod)
object:nil];


- (void)someMethod:(id)sender;


- (void)someMethod;

然后崩溃消失了。

同样,我也可以改变
[self.target performSelector:self.action];


[self.target performSelector:self.action withObject:nil];

如果我要遵循采用单个参数的目标操作方法的“标准”形式。 performSelector的第二种形式的好处是,如果我调用不带参数的方法,它将仍然可以正常工作。

关于xcode - 使用performSelector执行的方法中objc_retain崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11875900/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com