Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Objective-C Runtime编程指南(2)

Objective-C Runtime编程指南(2)

作者头像
Helloted
发布于 2022-06-06 10:52:16
发布于 2022-06-06 10:52:16
33000
代码可运行
举报
文章被收录于专栏:HellotedHelloted
运行总次数:0
代码可运行

苹果官方文档Objective-C Runtime Programming Guide

六、类型编码

为了帮助运行时系统,编译器将字符串中每个方法的返回值和参数类型进行编码,并将字符串与方法选择器相关联。 它使用的编码方案在其他上下文中也是有用的,所以通过@encode()编译器指令公开可用。 当给定类型规范时,@encode()返回一个编码该类型的字符串。 这个类型可以是一个基本的类型,比如int,指针,带标签的结构体或联合体,或者是一个类名,实际上,它可以用作C sizeof()运算符的参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
char *buf1 = @encode(int **);
char *buf2 = @encode(struct key);
char *buf3 = @encode(Rectangle);

下表列出了类型代码。 请注意,它们中的许多与用于存档或分发的对象编码时使用的代码重叠。 但是,这里列出的代码在编写代码时不能使用,并且在编写不是由@encode()生成的代码时,可能需要使用代码。

重要: Objective-C 不支持 long double 类型. @encode(long double) 返回 d, 与 double一样。

数组的类型代码用方括号括起来; 在数组类型之前,数组中元素的数目紧跟在开括号之后。 例如,一个由浮点数组成的12个指针的数组将被编码为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[12^f]

结构在大括号内指定,而在括号内结合。 首先列出结构标签,然后是等号和结构字段的代码。 例如,结构:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct example {
    id   anObject;
    char *aString;
    int  anInt;
} Example;

会被编码成这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{example=@*i}

不管定义的类型名称(example)还是结构标记(example)传递给@encode(),相同的编码都会生成。 结构指针的编码携带与结构字段相同的信息量:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
^{example=@*i}

但是,另一个间接级别删除了内部类型规范:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
^^{example}

对象被视为结构。例如,将NSObject类名称传递给@encode()会产生以下编码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{NSObject=#}

NSObject类只声明一个Class类型的实例变量isa。

请注意,尽管@encode()指令不返回它们,但运行时系统使用下表中列出的其他编码作为类型限定符,当它们用于在协议中声明方法时。

Code

Meaning

r

const

n

in

N

inout

o

out

O

bycopy

R

byref

V

oneway

七、声明的属性

当编译器遇到属性声明时,它会生成与包含的类,类别或协议相关联的描述性元数据。 您可以使用支持在类或协议上按名称查找属性,以@encode字符串的形式获取属性的类型以及将属性的属性列表复制为C字符串数组的函数来访问此元数据。 已声明的属性列表可用于每个类和协议。

属性类型和函数

Property结构定义了一个属性描述符的不透明处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct objc_property *Property;

您可以使用函数class_copyPropertyListprotocol_copyPropertyList分别检索与类(包括加载的类)和协议相关的属性数组:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
objc_property_t *protocol_copyPropertyList(Protocol *proto, unsigned int *outCount)

例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@interface Lender : NSObject {
    float alone;
}
@property float alone;
@end

你可以得到属性列表:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
id LenderClass = objc_getClass("Lender");
unsigned int outCount;
objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);

你可以使用property_getName函数去获取属性的名称

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const char *property_getName(objc_property_t property)

你可以使用函数class_getPropertyprotocol_getProperty分别获取对类中给定名称的属性的引用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
objc_property_t class_getProperty(Class cls, const char *name)
objc_property_t protocol_getProperty(Protocol *proto, const char *name, BOOL isRequiredProperty, BOOL isInstanceProperty)

您可以使用property_getAttributes函数来发现属性的名称和@encode类型的字符串

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const char *property_getAttributes(objc_property_t property)

把它们放在一起,你可以使用下面的代码打印一个与类关联的所有属性的list:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
id LenderClass = objc_getClass("Lender");
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);
for (i = 0; i < outCount; i++) {
    objc_property_t property = properties[i];
    fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
}
属性类型字符串

您可以使用property_getAttributes函数来发现名称,属性的@encode类型字符串以及属性的其他属性。

该字符串以T开头,后跟@encode类型和逗号,并以V结尾,后面跟着实例变量的名称。 在这些之间,属性由以下描述符指定,用逗号分隔

Code

Meaning

R

The property is read-only (readonly).

C

The property is a copy of the value last assigned (copy).

&

The property is a reference to the value last assigned (retain).

N

The property is non-atomic (nonatomic).

G<name>

The property defines a custom getter selector name. The name follows the G (for example, GcustomGetter,).

S<name>

The property defines a custom setter selector name. The name follows the S (for example, ScustomSetter:,).

D

The property is dynamic (@dynamic).

W

The property is a weak reference (__weak).

P

The property is eligible for garbage collection.

t<encoding>

Specifies the type using old-style encoding.

Property属性描述示例

给如下定义

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
enum FooManChu { FOO, MAN, CHU };
struct YorkshireTeaStruct { int pot; char lady; };
typedef struct YorkshireTeaStruct YorkshireTeaStructType;
union MoneyUnion { float alone; double down; };

下表显示了示例属性声明和property_getAttributes返回的相应字符串:

Property declaration

Property description

@property char charDefault;

Tc,VcharDefault

@property double doubleDefault;

Td,VdoubleDefault

@property enum FooManChu enumDefault;

Ti,VenumDefault

@property float floatDefault;

Tf,VfloatDefault

@property int intDefault;

Ti,VintDefault

@property long longDefault;

Tl,VlongDefault

@property short shortDefault;

Ts,VshortDefault

@property signed signedDefault;

Ti,VsignedDefault

@property struct YorkshireTeaStruct structDefault;

T{YorkshireTeaStruct="pot"i"lady"c},VstructDefault

@property YorkshireTeaStructType typedefDefault;

T{YorkshireTeaStruct="pot"i"lady"c},VtypedefDefault

@property union MoneyUnion unionDefault;

T(MoneyUnion="alone"f"down"d),VunionDefault

@property unsigned unsignedDefault;

TI,VunsignedDefault

@property int (*functionPointerDefault)(char *);

T^?,VfunctionPointerDefault

@property id idDefault;Note: the compiler warns: "no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed"

T@,VidDefault

@property int *intPointer;

T^i,VintPointer

@property void *voidPointerDefault;

T^v,VvoidPointerDefault

@property int intSynthEquals;In the implementation block:@synthesize intSynthEquals=_intSynthEquals;

Ti,V_intSynthEquals

@property(getter=intGetFoo, setter=intSetFoo:) int intSetterGetter;

Ti,GintGetFoo,SintSetFoo:,VintSetterGetter

@property(readonly) int intReadonly;

Ti,R,VintReadonly

@property(getter=isIntReadOnlyGetter, readonly) int intReadonlyGetter;

Ti,R,GisIntReadOnlyGetter

@property(readwrite) int intReadwrite;

Ti,VintReadwrite

@property(assign) int intAssign;

Ti,VintAssign

@property(retain) id idRetain;

T@,&,VidRetain

@property(copy) id idCopy;

T@,C,VidCopy

@property(nonatomic) int intNonatomic;

Ti,VintNonatomic

@property(nonatomic, readonly, copy) id idReadonlyCopyNonatomic;

T@,R,C,VidReadonlyCopyNonatomic

@property(nonatomic, readonly, retain) id idReadonlyRetainNonatomic;

T@,R,&,VidReadonlyRetainNonatomic


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
iOS runtime探究(三): 从runtime开始理解OC的属性property你要知道的runtime都在这里
你要知道的runtime都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 本文主要讲解runtime相关知识,从原理到实践,由于包含内容过多分为以下五篇文章详细讲解,可自行选择需要了解的方向: 从runtime开始: 理解面向对象的类到面向过程的结构体 从runtime开始: 深入理解OC消息转发机制 从runtime开始: 理解OC的属性property 从runtime开始: 实践Category添加属性与黑魔法method sw
WWWWDotPNG
2018/04/10
1.2K0
Objective-C Runtime:深入理解成员变量与属性
在上篇文章Objective-C Runtime:深入理解类与对象中,讲解了类与对象的相关内容。
Jacklin999
2018/09/12
8560
Objective-c 知识总结 -- @property
@property 只是一个编译器指令,意思是告诉编译器要干嘛,当然它的意思就是要求 Xcode 做属性声明了。
半纸渊
2018/09/04
1.5K0
Objective-c 知识总结 -- @property
Objective-C Runtime 的一些基本使用
在上一篇文章《Objective-C Runtime详解》中我们探讨了Runtime的基本原理,这篇文章我们将总结一下Runtime的一些基本使用 目录 查询方法 给分类添加属性 更换代码的实现方法 动态添加方法 字典转属性 先创建两个类 ClassA.h #import <Foundation/Foundation.h> @interface ClassA : NSObject { // 公有变量 NSString *_publicVar1; NSString *_publ
BY
2018/05/11
1.3K0
iOS开发·runtime原理与实践: 基本知识篇(类,超类,元类,super_class,isa,对象,方法,SEL,IMP)
Tips:苹果公开的源代码在这里可以查,https://opensource.apple.com/tarballs/
陈满iOS
2018/09/10
1.9K1
iOS开发·runtime原理与实践: 基本知识篇(类,超类,元类,super_class,isa,对象,方法,SEL,IMP)
Runtime系列(二)--Runtime的使用场景
Runtime 理解介绍的文章非常多,我只想讲讲Runtime 可以用在哪里,而我在项目里哪些地方用到了runtime。多以实际使用过程为主,来介绍runtime的使用。
Haley_Wong
2018/08/22
1.7K1
Runtime系列(二)--Runtime的使用场景
NSObject头文件解析 / 消息机制 / Runtime解读 (一)
上面是NSObject对象的头文件类部分, 可以看到还有一个NSObject protocol 我们也仔细看看都有什么协议方法@protocol NSObjec
周希
2019/10/15
1.3K0
iOS RunTime你知道了总得用一下
说点题外话: 我刚来现在这家公司的时候,老板让我下载一个脉脉,上去找找自己的同行,多认识些同行。其实初衷的好的,但最近这两天我把它卸载了,不为别的,负能量太多!iOS这行自从2016就没景气过,在这行混,这些自己也肯定都知道。但就是受不鸟铺天盖地的多久没找到工作,满大街都是iOS程序猿这些话题。看了也给我带不来任何的作用,你唯一能做的就是安安静静的做好自己该做的。自己入iOS这行也一年半过了,除去培训的那个几个月,真正摸爬滚打也一年多了,有时候想想,其实也没觉得有多差,以后怎样不知道,但至少现在,你有份工
Mr.RisingSun
2018/01/09
5940
iOS RunTime你知道了总得用一下
iOS runtime映射赋值
//  Copyright © 2016年 start. All rights reserved.
星宇大前端
2019/01/15
6710
利用Runtime实现简单的字典转模型
前言 我们都知道,开发中会有这么一个过程,就是将服务器返回的数据转换成我们自己定义的模型对象。当然服务器返回的数据结构有xml类型的,也有json类型的。本文只讨论json格式的。 大家在项目中一般是怎么样将服务器返回的json转化成自己定义的模型类呢? 我在项目中一般都是使用的MJExtension。 本文讲解的也基本就是解读MJExtension中的部分源码。 好了,废话不多说,直接上代码,let's go 简单字典转模型 首先,从最简单的字典开始,例如我们需要将如下的字典转化成自定义的模型。
Scott_Mr
2018/05/16
2K0
一种自动的将自定义类序列化为JSON的方法
最近因为项目需求,需要将一些自定义的类序列化为JSON,网上有很多好用的第三方序列化工具,但都只能自动序列化一些基本类型,如NSNumber,NSString与NSDictionary这种,没有一种第三方工具提供直接将自定义类序列化的方法(至少据我所知:),而对于这种序列化自定义的类的需求,网上能查到的方法只有将自定义的类手动的转存为一个NSDictionary,然后再使用第三方工具来序列化。例如对于一个类Foo,有如下定义: @interface Foo : NSObject {   NSStri
阿新
2018/04/12
1.2K0
深入浅出 Runtime(一):初识
对于 NSString *string = [[NSMutableArray alloc]init];
师大小海腾
2020/04/16
1.1K0
iOS 开发:『Runtime』详解(四)获取类详细属性、方法
文中示例代码在: bujige / YSC-Class-DetailList-Demo
程序员充电站
2019/08/02
3.1K0
动态的Objective-C——关于消息机制与运行时的探讨
    Objective-C是一种很优美的语言,至少在我使用其进行编程的过程中,是很享受他那近乎自然语言的函数命名、灵活多样的方法调用方式以及配合IDE流顺畅快编写体验。Objective-C是扩展与C面向对象的编程语言,然而其方法的调用方式又和大多面向对象语言大有不同,其采用的是消息传递、转发的方式进行方法的调用。因此在Objective-C中对象的真正行为往往是在运行时确定而非在编译时确定,所以Objective-C又被称为是一种运行时的动态语言。
珲少
2018/08/15
8970
动态的Objective-C——关于消息机制与运行时的探讨
Objective-C Runtime详解
Objective-C Runtime 最近在学习Runtime的知识,恰巧发现了这篇博客《Objective-C Runtime》,在此基础上,进行了些许补充说明,如有错误或其他想法,欢迎提出交流。 目录 引言 简介 与Runtime交互 RunTime术语 消息 动态方法解析 消息转发 健壮的实例变量 动态添加属性(Object-C Associated Objects) 方法调剂(Method Swizzling) 总结 引言 Objective-C的方法调用实则为“发送消息”,我们来看[dog
BY
2018/05/11
2.1K0
OC中Runtime浅析
最近了解了一下OC的Runtime,真的是OC中很强大的一个机制,看起来比较底层,但其实可以有很多活用的方式。
Cloudox
2021/11/23
3070
OC中Runtime浅析
runtime官方文档翻译版本通过OC源代码通过NSObject中定义的方法直接调用运行时的函数消息传递机制使用隐藏参数获取方法地址动态方法解析动态加载消息转发转发和多继承代理对象转发和继承类型编码声
本文只是单纯的翻译,如果您感觉枯燥可以参考我这篇比较实用的文章 文章地址,结合demo我相信您很快会熟悉runtime机制。 OC是一种面向对象的动态语言,作为初学者可能大多数人对面向对象这个概念理解的比较深,而对OC是动态语言这一特性了解的比较少。那么什么是动态语言?动态语言就是在运行时来执行静态语言的编译链接的工作。这就要求除了编译器之外还要有一种运行时系统来执行编译等功能。OC中这个系统就是runtime。 OC的runtime是用C语言和编译语言编写的一个runtime库,它使C语言有了面向对
用户2141756
2018/05/18
1.8K0
iOS开发·runtime原理与实践: 关联对象篇(Associated Object)(应用场景:为分类添加“属性”,为UI控件关联事件Block体,为了不重复获得某种数据)
分类(category)与关联对象(Associated Object)作为objective-c的扩展机制的两个特性:分类,可以通过它来扩展方法;Associated Object,可以通过它来扩展属性;
陈满iOS
2018/09/10
3.2K0
iOS开发·runtime原理与实践: 关联对象篇(Associated Object)(应用场景:为分类添加“属性”,为UI控件关联事件Block体,为了不重复获得某种数据)
Objc Runtime 总结
Objc Runtime使得C具有了面向对象能力,在程序运行时创建,检查,修改类、对象和它们的方法。Runtime是C和汇编编写的,这里http://www.opensource.apple.com/source/objc4/可以下到苹果维护的开源代码,GNU也有一个开源的runtime版本,他们都努力的保持一致。苹果官方的Runtime编程指南
用户7451029
2020/06/16
8650
iOS运行时(4)——常用函数
1 类 1.1 创建对象 id class_createInstance(Class cls, size_t extraBytes) eg: size_t size = class_getInstanceSize([Person class]); Person *person = class_createInstance([Person class], size); 1.2 获取类名 const char *class_getName(Class cls) eg const char *name = c
羊羽shine
2019/05/29
6110
推荐阅读
相关推荐
iOS runtime探究(三): 从runtime开始理解OC的属性property你要知道的runtime都在这里
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验