자체 NSZombie 구축
ObjZomies *oz = [[ObjZomies alloc] init];
oz.name = @"obz";
NSLog(@"ObjZomies :----%@---%s---%p",[ObjZomies class],object_getClassName(oz),oz);
[oz release];
NSLog(@"ObjZomies :-------%@----%s----%p",[ObjZomies class],object_getClassName(oz),oz);
oz.name = @"z----o";
인쇄 결과:
2015-10-27 17:32:43.303 Zombies[68811:1009530] ObjZomies :----ObjZomies---ObjZomies---0x7fcb71f047c0
2015-10-27 17:32:43.304 Zombies[68811:1009530] ObjZomies :-------ObjZomies----_NSZombie_ObjZomies----0x7fcb71f047c0
2015-10-27 17:32:43.304 Zombies[68811:1009530] *** -[ObjZomies setName:]: message sent to deallocated instance 0x7fcb71f047c0
신기한데...분석 로그에서 다음 정보를 얻을 수 있습니다.
1, 우리는'방출된 대상'ObjZomies에 setName: 방법을 보냈습니다.
2, oz가 release 앞뒤로 ObjectgetClassName(oz) 인쇄 결과가 다릅니다. 즉, oz의 isa가 가리키는 class가 0.0으로 바뀌었습니다.
ObjZomies와NSZombie_ObjZomies
3, 그 세 개의%p가 모두 같은 0x7fcb71f047c0이라는 것을 알아차리지 못했는가? 이것은 oz 이 물건이release 이후에 따로 방출되지 않았다는 것을 설명한다.
그래서'이미 풀린 대상'은 풀리지 않고'좀비'로 변해 프로그램이 실행되는 동안 메모리에 머물렀다.물론 xcode zombie 옵션을 사용하면 모든 종류가'좀비'로 변하는 것을 피할 수 없습니다
_NSZombie_ObjZomies는 당연히 실행할 때 추가된 클래스입니다. KVO처럼 목표 클래스가 A라면 실행할 때 특수한 기능을 가진 클래스 xxxA는 일부 기능을 행사한다.
_NSZombie_ 접두사 + ObjZomies는 실행할 때 만들어진 좀비 포착 기능 클래스를 구성합니다.
_NSZombie_MyClass는 좀비류를 잡는 것이고,
'이미 방출된 대상'에게 메시지를 보낼 때 이상을 촉발할 수 있는 메커니즘을 포착하고 개발자에게 구체적으로 방출된 클래스와 어떤 메시지를 보냈는지 알려주는 역할을 한다.
이것은 oc의 강력한 동태성과 메시지 전달 메커니즘에 의존한다.
원리를 간략하게 요약하다.
클래스 A의 실례 a의 인용 계수가 0일 때,delloc를 호출하여 메모리 정리 작업을 합니다. 물론 기본 클래스는 NSobject가 최종적으로 NSObject의 dealloc로 이동하는 것입니다.이때 만약 그것을 다 가게 한다면 a도 석방될 것이다.우리도 영원히 그것이 누군지 모른다.
그래서 a를 방출할 수 없다. a를'좀비'로 만들 수 있다. 즉, a의 메모리가 프로그램이 실행될 때 좀비를 잡는 클래스 B를 만들고 메시지가 a로 전송될 때 B에 이상을 던지며 관련 정보를 제시한다.즉, a-isa-->B는 a의 이사 바늘을 B에게 가리키고, (여기서 이해하지 못하는 것은 공부를 잘해야 한다) 그러면 a는 이사로 B에서 대응하는 것을 찾아낸다.
구현은 다음과 같습니다.
주의m 환경이 ARC가 아닌 경우 xcode zombie 관련 옵션 켜기
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import <objc/runtime.h>
#import "ObjZomies.h"
void EmpthIMP(id obj,SEL _cmd){}
NSMethodSignature * ZombieMethodSignatureForSelector(id obj,SEL _cmd,SEL selector){
Class class = object_getClass(obj);
NSString *className = NSStringFromClass(class);
className = [className substringFromIndex:[@"CMZombie_" length]];
NSLog(@"Selector %@ sent to deallocated instance %p of class %@", NSStringFromSelector(selector), obj, className);
abort();
return nil;
}
Class ZombifyClass(Class class){
NSString * className = NSStringFromClass(class);
NSString *zombieClassName = [@"CMZombie_" stringByAppendingString:className];
Class zombieClass = NSClassFromString(zombieClassName);
if (zombieClass) {
return zombieClass;
}
// NSZombie
zombieClass = objc_allocateClassPair(nil, [zombieClassName UTF8String], 0);
class_addMethod(zombieClass, @selector(methodSignatureForSelector:), (IMP)ZombieMethodSignatureForSelector, "@@::");
// ,+initialize MetaClass , Class 。
class_addMethod(object_getClass(zombieClass), @selector(initialize), (IMP)EmpthIMP, "v@:");
objc_registerClassPair(zombieClass);
return zombieClass;
}
void ZombieDealloc(id obj,SEL _cmd){
Class c = ZombifyClass(object_getClass(obj));
// obj isa " " _NSZombie_MyClass
object_setClass(obj, c);
}
void EnableZombies(void){
Method m = class_getInstanceMethod([NSObject class],@selector(dealloc));
method_setImplementation(m , (IMP)ZombieDealloc);
}
int main(int argc, char * argv[]) {
//
EnableZombies();
ObjZomies *oz = [[ObjZomies alloc] init];
oz.name = @"obz";
NSLog(@"ObjZomies :----%@---%s---%p",[ObjZomies class],object_getClassName(oz),oz);
[oz release];
NSLog(@"ObjZomies :-------%@----%s----%p",[ObjZomies class],object_getClassName(oz),oz);
oz.name = @"z----o";
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
#import <Foundation/Foundation.h>
@interface ObjZomies : NSObject
@property (nonatomic,copy) NSString *name;
@end
#import "ObjZomies.h"
@implementation ObjZomies
@end
다시 실행:
2015-10-27 17:55:55.433 Zombies[68883:1030347] ObjZomies :----ObjZomies---ObjZomies---0x7f825ae00790
2015-10-27 17:55:55.435 Zombies[68883:1030347] ObjZomies :-------ObjZomies----CMZombie_ObjZomies----0x7f825ae00790
2015-10-27 17:55:55.435 Zombies[68883:1030347] Selector setName: sent to deallocated instance 0x7f825ae00790 of class ObjZomies
so cool .
참조:https://www.mikeash.com/pyblog/friday-qa-2014-11-07-lets-build-nszombie.htmlhttp://www.cocoachina.com/ios/20141204/10526.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.