IOS-底层数据结构
Objective-C底层数据结构
类的数据结构
Class(指针)
typedef struct objc_class *Class; /*
这是由编译器为每个类产生的数据结构,这个结构定义了一个类.这个结构是通过编译器在执行时产生,在运行时发送消息时使用.因此,一些成员改变了类型.编译器产生"char* const"类型的字符串指针替代了下面的成员变量"super_class"
*/
struct objc_class {
struct objc_class* class_pointer; /* 指向元类的指针. */
struct objc_class* super_class; /* 指向父类的指针. 对于NSObject来说是NULL.*/
const char* name; /* 类的名称. */
long version; /* 未知. */
unsigned long info; /* 比特蒙板. 参考下面类的蒙板定义. */
long instance_size; /* 类的字节数.包含类的定义和所有父类的定义 */
#ifdef _WIN64
long pad;
#endif
struct objc_ivar_list* ivars; /* 指向类中定义的实例变量的列表结构. NULL代表没有实例变量.不包括父类的变量. */
struct objc_method_list* methods; /* 链接类中定义的实例方法. */
struct sarray * dtable; /* 指向实例方法分配表. */
struct objc_class* subclass_list; /* 父类列表 */
struct objc_class* sibling_class;
struct objc_protocol_list *protocols; /* 要实现的原型列表 */
void* gc_object_type;
};
Method(指针)
typedef struct objc_method *Method; /* 编译器依据类中定义的方法为该类产生一个或更多这种这种结构.
一个类的实现可以分散在一个文件中不同部分,同时类别可以分散在不同的模块中.为了处理这个问题,使用一个单独的方法链表 */
struct objc_method
{
SEL method_name; /* 这个变量就是方法的名称.编译器使用在这里使用一个`char*`,当一个方法被注册,名称在运行时被使用真正的SEL替代 */
const char* method_types; /* 描述方法的参数列表. 在运行时注册选择器时使用.那时候方法名就会包含方法的参数列表.*/
IMP method_imp; /* 方法执行时候的地址. */
};
Ivar(指针)
typedef struct objc_ivar *Ivar; /* 编译器依据类中定义的实例变量为该类产生一个或更多这种这种结构 */
struct objc_ivar
{
const char* ivar_name; /* 类中定义的变量名. */
const char* ivar_type; /* 描述变量的类型.调试时非常有用. */
int ivar_offset; /* 实例结构的基地址偏移字节 */
};
Category(指针)
typedef struct objc_category *Category; /* 编译器为每个类别产生一个这样的结构.一个类可以具有多个类别同时既包括实例方法,也可以包括类方法*/
struct objc_category
{
const char* category_name; /* 类别名.定义在类别后面的括号内*/
const char* class_name; /* 类名 */
struct objc_method_list *instance_methods; /* 链接类中定义的实例方法. NULL表示没有实例方法. */
struct objc_method_list *class_methods; /* 链接类中定义的类方法. NULL表示没有类方法. */
struct objc_protocol_list *protocols; /* 遵循的协议表 */
};
objc_property_t
typedef struct objc_property *objc_property_t;
IMP
id (*IMP)(id, SEL, ...)
SEL
typedef struct objc_selector *SEL; struct objc_selector
{
void *sel_id;
const char *sel_types;
};
objc_method_list
struct objc_method_list
{
struct objc_method_list* method_next; /* 这个变量用来链接另一个单独的方法链表 */
int method_count; /* 结构中定义的方法数量 */
struct objc_method method_list[1]; /* 可变长度的结构 */
};
objc_cache
struct objc_cache
{
unsigned int mask;
unsigned int occupied;
Method buckets[1];
};
objc_protocol_list
struct objc_protocol_list
{
struct objc_protocol_list *next;
size_t count;
struct objc_protocol *list[1];
};
实例的数据结构
id
typedef struct objc_object *id;
objc_object
struct objc_object
{
/* 类的指针是对象相关的类.如果是一个类对象, 这个指针指向元类.
Class isa;
};
objc_super
struct objc_super
{
id self; /* 消息的接受者 */
Class super_class; /* 接受者的父类 */
};
ios 底层数据结构
[array insertObject:foo atIndex:5];
objc_msgSend(array, @selector(insertObject:atIndex:), foo, 5);
typedef struct objc_object {
Class isa;
- (id)doSomethingWithInt:(int)aInt{}
其他运行时的方法
Class stringclass = NSClassFromString(@"NSString");
NSString *myString = [stringclass stringWithString:@"Hello World"];
- (void)parseObject:(id)object {
for (id data in object) {
if ([[data type] isEqualToString:@"String"]) {
[self parseString:[data value]];
} else if ([[data type] isEqualToString:@"Number"]) {
[self parseNumber:[data value]];
} else if ([[data type] isEqualToString:@"Array"]) {
[self parseArray:[data value]];
}
}
}
- (void)parseObjectDynamic:(id)object {
for (id data in object) {
[self performSelector:NSSelectorFromString([NSString stringWithFormat:@"parse%@:", [data type]]) withObject:[data value]];
}
}
- (void)parseString:(NSString *)aString {}
- (void)parseNumber:(NSString *)aNumber {}
- (void)parseArray:(NSString *)aArray {}
#import <objc/runtime.h>
@interface NSMutableArray (LoggingAddObject)
- (void)logAddObject:(id)aObject;
@end
@implementation NSMutableArray (LoggingAddObject)
+ (void)load {
Method addobject = class_getInstanceMethod(self, @selector(addObject:));
Method logAddobject = class_getInstanceMethod(self, @selector(logAddObject:));
}
- (void)logAddObject:(id)aobject {
[self logAddObject:aObject];
NSLog(@"Added object %@ to array %@", aObject, self);
}
@end
object_setClass(myObject, [MySubclass class]);
+ (BOOL)resolveInstanceMethod:(SEL)aSelector {
if (aSelector == @selector(myDynamicMethod)) {
class_addMethod(self, aSelector, (IMP)myDynamicIMP, "v@:");
return YES;
}
return [super resolveInstanceMethod:aSelector];
}
IMP myIMP = imp_implementationWithBlock(^(id _self, NSString *string) {
NSLog(@"Hello %@", string);
});
class_addMethod([MYclass class], @selector(sayHello:), myIMP, "v@:@");
IOS-底层数据结构的更多相关文章
- IOS底层数据结构--class
一.类的数据结构 Class(指针) typedef struct objc_class *Class; /* 这是由编译器为每个类产生的数据结构,这个结构定义了一个类.这个结构是通过编译器在执行时产 ...
- iOS底层原理总结 - 探寻block的本质(一)
面试题 block的原理是怎样的?本质是什么? __block的作用是什么?有什么使用注意点? block的属性修饰词为什么是copy?使用block有哪些使用注意? block在修改NSMu ...
- 深入浅出Redis-redis底层数据结构(上)
1.概述 相信使用过Redis 的各位同学都很清楚,Redis 是一个基于键值对(key-value)的分布式存储系统,与Memcached类似,却优于Memcached的一个高性能的key-valu ...
- 深入理解Redis:底层数据结构
简介 redis[1]是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...
- STL底层数据结构实现
C++ STL 的实现: 1.vector 底层数据结构为数组 ,支持快速随机访问 2.list 底层数据结构为双向链表,支持快速增删 3.deque 底层 ...
- 深入解析Java对象的hashCode和hashCode在HashMap的底层数据结构的应用
转自:http://kakajw.iteye.com/blog/935226 一.java对象的比较 等号(==): 对比对象实例的内存地址(也即对象实例的ID),来判断是否是同一对象实例:又可以说是 ...
- 深入浅出Redis-redis底层数据结构(下)
概述: 学习使用Redis,其实并不需要去研究其底层数据的实现.我们只需要了解他有哪些常用的数据类型,然后熟练使用,就可以很好的掌握Redis 这个工具了.但是这样的学习方法只适合Redis 的入门, ...
- Redis 概念以及底层数据结构
Redis 简介 REmote DIctionary Server(Redis) 是一个由SalvatoreSanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C ...
- Redis详解(四)------ redis的底层数据结构
上一篇博客我们介绍了 redis的五大数据类型详细用法,但是在 Redis 中,这几种数据类型底层是由什么数据结构构造的呢?本篇博客我们就来详细介绍Redis中五大数据类型的底层实现. 1.演示数据类 ...
- STL容器底层数据结构的实现
C++ STL 的实现: 1.vector 底层数据结构为数组 ,支持快速随机访问 2.list 底层数据结构为双向链表,支持快速增删 3.deque ...
随机推荐
- jQuery 对象
jQuery 对象 版权声明:未经博主授权,严禁转载分享 什么是 jQuery 对象 jQuery 对象是通过 jQuery 包装 DOM 对象后产生的对象. jQuery 对象是一个类数组对象. j ...
- Executor简析
本文只做简要解析,实际情形下我们多用spring的taskExecutor 直接使用new Thread()创建线程的缺点: 1.new Thread()耗费性能 2.调用new Thread()创建 ...
- noip杂题题解
这道题没有什么可说的,先统计,然后几次快排,答案就出来了 Code(整齐但不简洁的代码) #include<iostream> #include<cstdio> #includ ...
- 定义c/c++全局变量/常量几种方法的区别(转载)
出自:http://www.cnblogs.com/yaozhongxiao/archive/2010/08/08/1795338.html 在讨论全局变量之前我们先要明白几个基本的概念: 1. 编 ...
- Python3基础 if else 格式 输入一个整数并判断是8吗
Python : 3.7.0 OS : Ubuntu 18.04.1 LTS IDE : PyCharm 2018.2.4 Conda ...
- ubuntu下进程kidle_inject致使编译软件很慢
一.背景 某一天编译一个程序发现半天都没编译ok,于是使用top一看发现有个别进程占用cpu奇高,遂出此文 二.怎么解决? 2.1 什么进程占据很高cpu 名为kidle_inject,同时开启了好几 ...
- CF873B Balanced Substring
1到n内0,1个数相同的个数的最长字串 \(i>=j\) \[1的个数=0的个数\] \[sum[i]-sum[j-1]=i-(j-1) - (sum[i]-sum[j-1])\] 这里把\(( ...
- zedgraph多个graphpane的处理
这个问题需要研究,需要使用 zedgraph.masterpane.panelist 其他人做的效果--先预留一个官网的链接http://zedgraph.dariowiz.com/index113 ...
- 【第二十五章】 springboot + hystrixdashboard
注意: hystrix基本使用:第十九章 springboot + hystrix(1) hystrix计数原理:附6 hystrix metrics and monitor 一.hystrixdas ...
- 网络压缩论文整理(network compression)
1. Parameter pruning and sharing 1.1 Quantization and Binarization Compressing deep convolutional ne ...