前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Objective-C Runtime编程指南(2)

Objective-C Runtime编程指南(2)

作者头像
Helloted
发布2022-06-06 18:52:16
2970
发布2022-06-06 18:52:16
举报
文章被收录于专栏:Helloted

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

六、类型编码

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

代码语言:javascript
复制
char *buf1 = @encode(int **);
char *buf2 = @encode(struct key);
char *buf3 = @encode(Rectangle);

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

img
img

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

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

代码语言:javascript
复制
[12^f]

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

代码语言:javascript
复制
typedef struct example {
    id   anObject;
    char *aString;
    int  anInt;
} Example;

会被编码成这样:

代码语言:javascript
复制
{example=@*i}

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

代码语言:javascript
复制
^{example=@*i}

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

代码语言:javascript
复制
^^{example}

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

代码语言:javascript
复制
{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
复制
typedef struct objc_property *Property;

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

代码语言:javascript
复制
objc_property_t *class_copyPropertyList(Class cls, unsigned int *outCount)
objc_property_t *protocol_copyPropertyList(Protocol *proto, unsigned int *outCount)

例如:

代码语言:javascript
复制
@interface Lender : NSObject {
    float alone;
}
@property float alone;
@end

你可以得到属性列表:

代码语言:javascript
复制
id LenderClass = objc_getClass("Lender");
unsigned int outCount;
objc_property_t *properties = class_copyPropertyList(LenderClass, &outCount);

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

代码语言:javascript
复制
const char *property_getName(objc_property_t property)

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

代码语言:javascript
复制
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
复制
const char *property_getAttributes(objc_property_t property)

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

代码语言:javascript
复制
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
复制
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 删除。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 六、类型编码
  • 七、声明的属性
    • 属性类型和函数
      • 属性类型字符串
        • Property属性描述示例
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档