iOSプレミアム開発runtimeの件実戦(2)
4262 ワード
classのpropertyプロパティリストの取得
-(void)printPropertyList{
unsigned int count ;//
objc_property_t * methodsVar = class_copyPropertyList([UINavigationController class], &count) ;
for (int i = 0; i < count; i ++) {
objc_property_t var = methodsVar[i] ;
NSString * strName =[NSString stringWithUTF8String:property_getName(var)];
NSString * str =[NSString stringWithUTF8String:property_getAttributes(var)];
NSLog(@" %@ %@",str,strName);
}
free(methodsVar);
}
classの名前を取得
-(void)printfClassName{
Class clas = NSClassFromString(@"NSString");
printf("%s", class_getName(clas)); // clas return value nil
}
:NSString
クラスの親を取得して出力
-(void)printfClassName:(Class )clas{
printf("%s", class_getName(clas));
}
-(Class)getSuperClass:(Class)clas{
return class_getSuperclass(clas);
}
[self printfClassName:[self getSuperClass:NSClassFromString(@"UIView")]];
:UIResponder
クラスの親の設定
/**
* Sets the superclass of a given class.
*
* @param cls The class whose superclass you want to set.
* @param newSuper The new superclass for cls.
*
* @return The old superclass for cls.
*
* @warning You should not use this function.
*/
OBJC_EXPORT Class class_setSuperclass(Class cls, Class newSuper)
__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5,__MAC_10_5, __IPHONE_2_0,__IPHONE_2_0);
[self printfClassName:[self getSuperClass:NSClassFromString(@"FY")]]; NSObjec
[self setClass:NSClassFromString(@"FY") newSuperClass:NSClassFromString(@"UIImageView")];//
[self printfClassName:[self getSuperClass:NSClassFromString(@"FY")]];// UIImageView
-(void)printfClassName:(Class )clas{
printf("%s
", class_getName(clas));
}
-(Class)getSuperClass:(Class)clas{
return class_getSuperclass(clas);
}
-(Class)setClass:(Class)clas newSuperClass:(Class)superClas{
return class_setSuperclass(clas, superClas);
}
オブジェクトとクラスの区分
-(void)isMetaClass{
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:[NSObject class]];
[arr addObject:[NSValue class]];
[arr addObject:[NSNumber class]];
[arr addObject:[NSPredicate class]];
[arr addObject:@"not a class object"];
for (int i; i
クラスが占めるバイトのサイズを取得
size_t size = class_getInstanceSize(NSClassFromString(@"UIView"));
printf("%zu",size);
クラスのプロパティとそのプロパティのタイプを取得
-(void)ivarList{
unsigned int count;
Ivar * vars = class_copyIvarList(NSClassFromString(@"UIViewController"), &count)//ivar name,offset,type 。
;
for (int i = 0; i < count; i ++) {
Ivar var = vars[i];
[self printIvar:var];
}
free(vars);
}
-(void)printIvar:(Ivar)var{//
const char * name = ivar_getName(var);
long offset = ivar_getOffset(var);
const char * type = ivar_getTypeEncoding(var);
printf("%s %ld %s
",name,offset,type);
}
:
_storyboard 152 @"UIStoryboard"
_externalObjectsTableForViewLoading 160 @"NSDictionary"
_topLevelObjectsToKeepAliveFromStoryboard 168 @"NSArray"
_savedHeaderSuperview 176 @"UIView"
_savedFooterSuperview 184 @"UIView"
これらはapple Objectice-C Runtime Referenceで、具体的にはこのサイトでもっと見られます.
前編で述べた方法名は
void method_exchangeImplementations(Method m1, Method m2)
です.この交換方法は1回しか実行できないので、交換を2回解決したのは、交換していないことに相当します.具体的なコード:static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
void (^__method_swizzling)(Class, SEL, SEL) = ^(Class cls, SEL sel, SEL _sel) {
Method method = class_getInstanceMethod(cls, sel);
Method _method = class_getInstanceMethod(cls, _sel);
method_exchangeImplementations(method, _method);
};
}
ここではこの方法をc関数にカプセル化し,一度しか実行できないことを保証し,この
dispatch
を+ load
関数に入れ,ロード回数の減少を保証したほうがよい.その他のブログはwww.fgyong.cnが表示されます.