代码在ARC下。当我删除代码NSObject* objc = (NSObject*)object;
时,程序可以正常运行,但是我无法访问指针objc
。当我保留代码NSObject* objc = (NSObject*)object;
时,系统会提示EXC_BAD_ACCESS (code=1, address=0x20)
。块功能主体结束后,系统是否正在访问objc
指针?
-(void)resetDeallocMethodWithInstance:(NSObject*)obj
{
Class targetClass = obj.class;
@synchronized (swizzledClasses()) {
NSString *className = NSStringFromClass(obj.class);
if ([swizzledClasses() containsObject:className]) return;
SEL deallocSel = sel_registerName("dealloc");
__block void (*deallocBlock)(__unsafe_unretained id, SEL) = NULL;
id block = ^(__unsafe_unretained id object){
NSObject* objc = (NSObject*)object;
NSUInteger hash = ((NSObject*)object).hash;
[self removeAllTargetWitSuffixKey:[NSString stringWithFormat:@"%lu",(unsigned long)hash]];
if (deallocBlock == NULL) {
struct objc_super superInfo = {
.receiver = object,
.super_class = class_getSuperclass(targetClass)
};
void (*msgSend)(struct objc_super *, SEL) = (__typeof__(msgSend))objc_msgSendSuper;
msgSend(&superInfo, deallocSel);
} else {
deallocBlock(object, deallocSel);
}
};
IMP blockImp = imp_implementationWithBlock(block);
if (!class_addMethod(obj.class, deallocSel, blockImp, "v@:")) {
Method deallocMethod = class_getInstanceMethod(obj.class, deallocSel);
deallocBlock = (__typeof__(deallocBlock))method_getImplementation(deallocMethod);
deallocBlock = (__typeof__(deallocBlock))method_setImplementation(deallocMethod, blockImp);
}
[swizzledClasses() addObject:className];
}
return;
}
答案 0 :(得分:2)
注意:此答案是直接输入的,您的代码未未经过测试,实际上否已受过测试。因此,可以推断出以下问题正在导致您的问题。
您的设计存在许多问题:
dealloc
。 dealloc
方法在销毁对象的过程中会自动被系统调用,例如,不当使用部分销毁的对象(无论可能如何)都可能导致问题-如您所见!objc
未使用。但是,默认情况下,局部变量具有属性strong
,因此您要在销毁过程中创建对对象的强引用。块完成后,ARC会释放该块以这种方式做出的任何强引用,几乎可以肯定这不是您的错误所表明的。当特定对象被销毁时,您似乎正在尝试调用removeAllTargetWithSuffixKey:
方法(出现,当您烦恼[并且只能烦恼] 类但正在使用特定对象的hash
)。避免混淆的更好方法是使用关联对象。
运行时函数objc_setassociatedobject()
允许您将一个对象附加到另一个对象的特定实例,并在销毁其主机时自动销毁该对象(使用objc_AssociationPolicy
中的OBJC_ASSOCIATION_RETAIN
)。
设计一个类,该类具有您所需的hash
值的实例属性和一个dealloc
方法,该方法调用您的removeAllTargetWithSuffixKey:
,然后不必烦恼该类,只需创建并关联您的实例类与目标对象。
HTH
答案 1 :(得分:0)
是的,方法结束后它正在访问指针。如果在ARC下进行编译,则objc是“强”引用。但是,您正在构造 dealloc 方法的实现,并且在对象已经要被分配时也保留了该对象,因此对它进行强大的引用为时已晚。您的实现将调用super,它实际上应该取消分配对象,然后ARC将释放objc值,但是由于它是接收者,所以已经消失了,如果您正在编写普通的dealloc方法,则为“ self”。 / p>
ARC永远不会将自己保留在常规的dealloc方法中,但这就是您正在有效地做的事情。 “对象”值是相同的指针,但是显式是__unsafe_unretained,因此您应该直接使用它。如果有帮助,您可以将块键入NSObject *而不是id,但这没关系。或者,您也可以将objc值也设置为__unsafe_unretained,以便ARC不用管它。您不希望ARC以任何方式触摸块内的“自我”值,因为在这种情况下,您将绕过ARC的背面。
无论如何,一旦进入对象的dealloc方法,就永远不要保留/释放/自动释放自指针,否则将导致崩溃。例如,从dealloc调用方法并将引用传递给self是不可以的。您需要对此非常小心,并且如果您正在玩这些类型的运行时游戏,则必须确切了解ARC在做什么。