AutoLisp 函数总括

Rust
1.40.0 已经正式公布。该版本的亮点包涵有 #[non_exhaustive] 和 macros!() and #[attribute]s 的改进。

在本章中,大家将越来越多研商关于在Visual
LISP中动用ActiveX品质。首先,大家从ActiveX的技能条件早先,蕴含对象、对象模型、集合、属性、方法等方面。然后我们将深挖一些一定的ActiveX技能部分。通晓ActiveX效能性是上学其余语言不能够缺乏的办事。

attribute是GNU C特色之一,在iOS用的相比普遍.系统中有那几个地点使用到.
attribute能够安装函数属性(Function Attribute )、变量属性(Variable
Attribute )和品种属性(Type Attribute卡塔尔国等.

1.Preprocessor Glue: The ## Operator

切切实实更新内容如下:

ActiveX是一种面向对象的工具,也正是说它表现为指标的选拔以致对象间的涉嫌这种艺术。在这里间本身不想去解释面向对象的标题,这一个东西最佳留下那多少个更标准的读本去讲。可是,笔者将尝试给部分基本的面向对象方面包车型地铁描述,以便我们有八个着力的问询。

函数属性(Function Attribute卡塔尔

  • noreturn
  • noinline
  • always_inline
  • pure
  • const
  • nothrow
  • sentinel
  • format
  • format_arg
  • no_instrument_function
  • section
  • constructor
  • destructor
  • used
  • unused
  • deprecated
  • weak
  • malloc
  • alias
  • warn_unused_result
  • nonnull

预管理连接符:##操作符

#[non_exhaustive] 结构,枚举和变体

品类属性(Type Attributes卡塔尔国

  • aligned
  • packed
  • transparent_union,
  • unused,
  • deprecated
  • may_alias

Like the # operator, the ## operator can be used in the replacement
section of a function-like macro.Additionally, it can be used in the
replacement section of an object-like macro. The ## operator combines
two tokens into a single token. 

当属性#[non_exhaustive]附加到struct或的变体时enum,它将防范定义它的棉条箱外部的代码构造所述struct或变体。为了制止未来破坏,还防止别的包装箱在水浇地上进行深透相称。以下示例表明了beta有赖于的荒诞alpha

在面向对象的条件中,任何事物都是以Classes(类卡塔尔国起首的。类是空洞的框架,用于描述对象应是怎么着的,以至她们理应怎样表现和人机联作关系的。在某种意义上说类定义了目的类型的品类。比方,一辆汽车是归属交通工具类。交通工具是父类,而汽车是子类。反之,你可获得愈来愈多特定的和额外定义的子类,譬喻参观车、面包车和平运动动型汽车。

变量属性(Variable AttributeState of Qatar

  • aligned
  • packed

##将五个标记连接成三个。

// alpha/lib.rs:

#[non_exhaustive]
struct Foo {
    pub a: bool,
}

enum Bar {
    #[non_exhaustive]
    Variant { b: u8 }
}

fn make_foo() -> Foo { ... }
fn make_bar() -> Bar { ... }

// beta/lib.rs:

let x = Foo { a: true }; //~ ERROR
let Foo { a } = make_foo(); //~ ERROR

// `beta` will still compile when more fields are added.
let Foo { a, .. } = make_foo(); //~ OK


let x = Bar::Variant { b: 42 }; //~ ERROR
let Bar::Variant { b } = make_bar(); //~ ERROR
let Bar::Variant { b, .. } = make_bar(); //~ OK
                   // -- `beta` will still compile...

类不管理特定的实例,他们更注重于实例方面包车型大巴描述,而非使用方面。当你利用类时,你能够说调用类的三个实例。调用类的结果经常是创制了叁个对象。对象能够是单身的图元或带有了越来越多指标的容器。

Clang特有的

  • availability
  • overloadable

For example, you could do this:

悄悄时有爆发的事情是,#[non_exhaustive] struct或的布局函数的可知性enum降低到pub(crate),进而阻碍了在概念它的紫穗槐箱外部实行访问。

对象
四个目的正是类的多个实例。对象有其恒久的属性,同一时候也得以有定位的艺术和事件。属性是概念对象怎么着表现和反应的特色。方法是用来访谈或更换对象属性或一些行为的放松权利函数。事件是由对象发送的文告,当实践或激活它们时,它用来响应特定动作。

书写格式

挥洒格式:attribute末端会紧跟一对原括弧,括弧里面是对应的attribute参数

__attribute__(xxx)

#define XNAME(n) x ## n

更珍视的方面是,#[non_exhaustive]也足以增大到enum本人上。从规范库中取得的示范是Ordering

就用地点的小车类的例子来讲,对象足以是专门的小小车。比如说,你的小汽车,带有特别的配置(成立、型号、颜色、选配、以至种类号卡塔尔。你能够说,你的小车是小车类的一个实例,或小车类派生的一对类。

普遍的种类用法

Then the macro

#[non_exhaustive]
pub enum Ordering { Relaxed, Release, Acquire, AcqRel, SeqCst }

图3-1 对象模型

format

合法例子:NSLog

 #define NS_FORMAT_FUNCTION(F,A) __attribute__((format(__NSString__, F, A)))

format属性可以给被声称的函数加上形似printf恐怕scanf的特色,它能够使编写翻译器检查函数注明和函数实际调用参数之间的格式化字符串是不是相配。该作用特别有用,极度是管理局地很难发掘的bug。对于format参数的行使如下
format (archetype, string-index, first-to-check)
先是参数须要传递“archetype”钦点是哪一种风格,这里是
NSString;“string-index”内定传入函数的第多少个参数是格式化字符串;“first-to-check”钦定第二个可变参数所在的索引.

XNAME(4)

#[non_exhaustive]在这上下文中的指标是确定保证能够任何时候间增加更加多变体。那是由此防范其余包装箱从详尽形式完毕match-ing上Ordering。也正是说,编写翻译器将不容:

对象模型
目的模型是叁个任性的布局,或类之间的分支定义的排列关系,意思正是足以从越来越高等别的类来获取叁个指标。对象模型与拜访它的语言或工具无关,它有谈得来的逻辑框架。不管你是使用Visual
Basic、VBA、Visual
LISP、Delphi、Java、C/C++、C#.NET或含有ActiveX接口的别的语言,它都将以相仿的模子存在。那并不代表对象模型的装有个性都帮忙具有语言。有些特点在有些语言中能够访谈或比比较简单于被访谈,但在别的语言中也许就丰裕。

noreturn

法定例子: abort(卡塔尔(قطر‎ 和 exit(卡塔尔

该属性通告编写翻译器函数从不重回值。当境遇相通函数还未有运行到return语句就要求退出来的状态,该属性能够幸免出现错误消息。

would expand to the following:

match ordering {
    // This is an error, since if a new variant is added,
    // this would suddenly break on an upgrade of the compiler.
    Relaxed | Release | Acquire | AcqRel | SeqCst => {
        /* logic */
    }
}

大家将对象模型比喻成一套房子,它由房间、门和窗组成。不一致的人都可进入和动用屋企,而她们都是直面相仿的那套房屋。在此种情状下,屋家和房间正是指标模型,而人便是编程语言。那样,你应当懂吗。

availability

法定例子:

- (CGSize)sizeWithFont:(UIFont *)font NS_DEPRECATED_IOS(2_0, 7_0, "Use -sizeWithAttributes:") __TVOS_PROHIBITED;

//来看一下 后边的宏
 #define NS_DEPRECATED_IOS(_iosIntro, _iosDep, ...) CF_DEPRECATED_IOS(_iosIntro, _iosDep, __VA_ARGS__)

define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...) __attribute__((availability(ios,introduced=_iosIntro,deprecated=_iosDep,message="" __VA_ARGS__)))

//宏展开以后如下
__attribute__((availability(ios,introduced=2_0,deprecated=7_0,message=""__VA_ARGS__)));
//ios即是iOS平台
//introduced 从哪个版本开始使用
//deprecated 从哪个版本开始弃用
//message    警告的消息

availability属性是贰个以逗号为分隔的参数列表,以平台的称谓开首,包罗部分位居附加音信里的有的里程碑式的宣示。

  • introduced:第贰遍面世的本子。

  • deprecated:注解要毁弃的版本,意味着顾客要搬迁为此外API

  • obsoleted: 评释移除的本子,意味着完全移除,再也不可能使用它

  • unavailable:在这里些平台不可用

  • message:一些关于遗弃和移除的额外音信,clang发出警报的时候会提供那一个音讯,对顾客使用替代的API极度管用。

  • 本条天性扶植的平台:ios,macosx。

轻易易行例子:

//如果经常用,建议定义成类似系统的宏
- (void)oldMethod:(NSString *)string __attribute__((availability(ios,introduced=2_0,deprecated=7_0,message="用 -newMethod: 这个方法替代 "))){
    NSLog(@"我是旧方法,不要调我");
}

- (void)newMethod:(NSString *)string{
    NSLog(@"我是新方法");
}

效果:

图片 1

Paste_Image.png

//假若调用了,会有警示

图片 2

Paste_Image.png

x4

替代的是,别的紫穗槐箱供给经过加多通配符来减轻越来越多变体的或者性,例如_

类继承
对象模型日常都以从根或源对象开首。在AutoCAD中,源对象是AutoCAD
Application
(AutoCAD应用程序卡塔尔对象,也被称之为AcadApplication对象。它提供了基本的品质、方法、事件和来自具有其余对象和集纳构成的集合。比如,AcadApplication对象有一集中为Documents(即Documents集结卡塔尔(قطر‎,在内部对应当二个或八个Document对象。每一Document对象有它本人的对象、群集、属性和措施以致其余东西。

unavailable

告知编写翻译器该措施不可用,即便强行调用编写翻译器会提醒错误。比如某些类在构造的时候不想直接通过init来起初化,只好通过一定的开始化方法(卡塔尔国例如单例,就能够将init方法标识为unavailable;

//系统的宏,可以直接拿来用
 #define UNAVAILABLE_ATTRIBUTE __attribute__((unavailable))

 #define NS_UNAVAILABLE UNAVAILABLE_ATTRIBUTE

@interface Person : NSObject

@property(nonatomic,copy) NSString *name;

@property(nonatomic,assign) NSUInteger age;

- (instancetype)init NS_UNAVAILABLE;

- (instancetype)initWithName:(NSString *)name age:(NSUInteger)age;

@end

图片 3

Paste_Image.png

//实际上unavailable前边能够跟参数,显示一些音信,如:

//系统的
 #define NS_AUTOMATED_REFCOUNT_UNAVAILABLE __attribute__((unavailable("not available in automatic reference counting mode")))

Listing 1 uses this and another macro using ## to do a bit of token
gluing.

match ordering {
    Relaxed | Release | Acquire | AcqRel | SeqCst => { /* ... */ }
    // OK; if more variants are added, nothing will break.
    _ => { /* logic */ }
}

您可向下层浏览对象模型步入下一档案的次序的对象和会集,也得以向上层浏览父对象和聚合。模型非常常有力,应用程序可平昔访谈和操作境况来实行差相当的少无以复加的义务。它同有时间保持每一事物都有次序有序,在开拓软件技术方案时能提供实用的帮扶。

objc_root_class

表示那一个类是一个根类(基类卡塔尔,比方NSObject,NSProxy.

//摘自系统
//NSProxy
NS_ROOT_CLASS
@interface NSProxy <NSObject> {
    Class   isa;
}

//NSObject
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0)
OBJC_ROOT_CLASS
OBJC_EXPORT
@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

 

有关该#[non_exhaustive]性子的更加多详细消息,可参见安宁报告。

聚焦和辞典
汇集是在长期以来父窗口中一组平日的对象。该容器有一个极其的名字,在大部分意况下,将提供温馨的章程来寻访所包括的靶子。字典是一种特有类型的联谊,它同意你扩张你协和的辞书。Visual
LISP并从未过多提供用于创立或管理集合的格局。它同意你遍历它、校订项目、增添或删除条目款项。辞书允许你加多本身的词典并写入数据,你可遍历它、增加、改正和删除其条目,同样,你也得以增添、修正和删除词典本人。

NSObject

@property (nonatomic,strong) __attribute__((NSObject)) CFDictionaryRef myDictionary;

CFDictionaryRef属于CoreFoundation框架的,也正是非OC对象,加上attribute((NSObjectState of QatarState of Qatar后,myDictionary的内部存款和储蓄器管理会被当作OC对象来对待.

// glue.c — use the ## operator

Macro and attribute 的改进

在AutoCAD中的一些国有的集合有Documents(文书档案卡塔尔(قطر‎、Layers(图层卡塔尔国、Dimension
Styles(评释样式卡塔尔、Linetypes(线型State of Qatar、 Blocks(块卡塔尔国等等。

objc_designated_initializer

用来修饰类的designated
initializer起始化方法,即使修饰的办法里不曾调用super类的 designated
initializer,编写翻译器会爆发警报。可以简写成NS_DESIGNATED_INITIALIZER

那篇小说讲的很好,提议参照他事他说加以侦察那么些.
https://yq.aliyun.com/articles/5847

#include <stdio.h>

  • 在 type
    contexts 中调用 procedural
    macros mac!() 。

在AutoCAD中的一些共用的词典有PageSetups (页面设置卡塔尔、Layouts
(布局卡塔尔国(它一律也做为词典保存State of Qatar,还大概有Express Tools中的个别组件,如WipeOuts
(遮罩State of Qatar。Xrecord对象也保留在词典内。

visibility

语法:

__attribute__((visibility("visibility_type")))

其中,visibility_type 是下列值之一:

  • default
    一经的标志可知性可经过此外选用进行转移。缺省可以见到性将隐讳此类校勘。缺省可知性与表面链接对应。

  • hidden
    该符号不寄存在动态符号表中,由此,其余可实践文件或分享库都不恐怕直接引用它。使用函数指针可进行直接援引。

  • internal
    唯有由 特定于微处理器的应用二进制接口 (psABIState of Qatar钦命,不然,内部可以知道性意味着差别意从另一模块调用该函数。

  • protected
    该符号存放在动态符号表中,但定义模块内的引用将与一些符号绑定。也便是说,另一模块不恐怕覆盖该符号。

  • 除钦点 default
    可知性外,此属性都可与在此些境况下全体外界链接的注脚结合使用。
    您可在 C 和 C++ 中利用此属性。在 C++
    中,还可将它选取于类型、成员函数和命名空间证明。

系统用法:

//  UIKIT_EXTERN     extern
 #ifdef __cplusplus
 #define UIKIT_EXTERN        extern "C" __attribute__((visibility ("default")))
 #else
 #define UIKIT_EXTERN            extern __attribute__((visibility ("default")))
 #endif

#define XNAME(n) x ## n

比方,顾客能够编写以下项目:Foo = expand_to_type!(bar); 其中
expand_to_type 将是一个 procedural macro。

质量、方法和事件
属性只是描述关联于对象或集结的特点。举个例子它可含蓄名称、中度、宽度、旋转角度、比例缩放、颜色、图层、线型等等。属性依据分化的靶子的档案的次序而有所不一致,但稍事属性对具有指标和集中是通用的。集合和词典平时提供了Count和Name属性,还大概有Item和Add方法。唯有词典提供了Delete方法,而你却无法透过Visual
LISP删除集结。

nonnull

编写翻译器对函数参数实行NULL的自己切磋,参数类型必须是指针类型(蕴涵对象卡塔尔(قطر‎
//使用

- (int)addNum1:(int *)num1 num2:(int *)num2  __attribute__((nonnull (1,2))){//1,2表示第一个和第二个参数不能为空
    return  *num1 + *num2;
}

- (NSString *)getHost:(NSURL *)url __attribute__((nonnull (1))){//第一个参数不能为空
    return url.host;
}

#define PRINT_XN(n) printf(“x” #n ” = %d\n”, x ## n);

  • Macros
    in extern { ... } blocks.

形式是指标提供的用于访问或编辑专用个性或针对对象自己奉行特别动作的放置函数。习感觉常的格局有Rotate(旋转卡塔尔(قطر‎、伊Russe(删除卡塔尔、Copy(复制卡塔尔国、Scale(比例缩放卡塔尔和Offset(偏移卡塔尔(قطر‎。你可能注意到,这几个看起来就疑似AutoCAD编辑命令。嗯,在真相上是这样的,但略有不一样。

大范围用法

int main(void)

包括有bang!() macros, 例如:

唯唯平日的AutoCAD编辑命令,必得在每步推行中证消肿标。而艺术是由主对象提供的,因而,只可以由每一对象单独提供扶助的点子。晕了啊?

aligned

__attribute((aligned
(n卡塔尔国State of Qatar卡塔尔,让所出力的布局成员对齐在n字节本来边界上。假诺组织中有成员的长度抢先n,则依据最大成员的尺寸来对齐.比如:

不加修饰的状态

typedef struct
{
    char  member1;
    int   member2;
    short member3;
}Family;

//输出字节:
NSLog(@"Family size is %zd",sizeof(Family));
//输出结果为:
2016-07-25 10:28:45.380 Study[917:436064] Family size is 12

//改良字节对齐为1

typedef struct
{
    char  member1;
    int   member2;
    short member3;
}__attribute__ ((aligned (1))) Family;

//输出字节:
NSLog(@"Family size is %zd",sizeof(Family));
//输出结果为:
2016-07-25 10:28:05.315 Study[914:435764] Family size is 12

和上边的结果一律,因为 设定的字节对齐为1.而构造体中成员的最大字节数是int
4个字节,1 < 4,依照4字节对齐,和种类暗许一致.

更改字节对齐为8

typedef struct
{
    char  member1;
    int   member2;
    short member3;
}__attribute__ ((aligned (8))) Family;

//输出字节:
NSLog(@"Family size is %zd",sizeof(Family));
//输出结果为:
2016-07-25 10:28:05.315 Study[914:435764] Family size is 16

那边 8 >
4,依照8字节对齐,结果为16,不掌握字节对齐的能够看自个儿的那篇作品http://www.jianshu.com/p/f69652c7df99

而是想了半天,也不清楚那东西有哪些用,设定值小于系统默许的,和没设定近似,设定大了,又浪费空间,功能也没增进,感觉学习深作育好.

{

macro_rules! make_item { ($name:ident) => { fn $name(); } }

extern {
    make_item!(alpha);
    make_item!(beta);
}

另一种艺术,OFFSET(偏移卡塔尔国命令可以在任什么时候刻利用,但倘若您打算偏移一个文本对象,
AutoCAD就汇合世失误消息。不过,文本对象自己提供的各样艺术,如Copy(复制State of Qatar、Rotate(旋转卡塔尔(قطر‎、Scale(比例缩放卡塔尔(قطر‎和Move(移动State of Qatar,但尚无Offset(偏移卡塔尔。所以你能够从指标“调用”各类法子,却供给明确它对应用的靶子是有效的。

packed

让钦命的构造构造体依照一字节对齐,测验:

//不加packed修饰
typedef struct {
    char    version;
    int16_t sid;
    int32_t len;
    int64_t time;
} Header;

//计算长度
NSLog(@"size is %zd",sizeof(Header));
输出结果为:
2016-07-22 11:53:47.728 Study[14378:5523450] size is 16

能够看看,默许系统是坚决守住4字节对齐

//加packed修饰
typedef struct {
    char    version;
    int16_t sid;
    int32_t len;
    int64_t time;
}__attribute__ ((packed)) Header;

//计算长度
NSLog(@"size is %zd",sizeof(Header));
输出结果为:
2016-07-22 11:57:46.970 Study[14382:5524502] size is 15

用packed修饰后,变为1字节对齐,这一个常用于与商业事务有关的互联网传输中.

int XNAME(1) = 14; // becomes int x1 = 14;

Procedural macro attributes on items
in extern { ... } blocks 今后也被协助:

事件是目的或群集由各类能够被检验到的或能够响应的位移所发生动作。当事件与那么些事件的影响相结合使用时,就叫做事件驱动编制程序。AutoCAD提供了一个被叫做反应器的强盛的风云反应工具集,它令你可在绘图情况中发送触发器来响应各样风浪。比方,当对象在移动的图片中被去除时,您可以创制二个反应器响应三个伊Russe事件。那只是八个事件和反应器的事例。

noinline & always_inline

内联函数:内联函数从源代码层看,有函数的布局,而在编写翻译后,却不享有函数的习性。内联函数不是在调用时产生调控转移,而是在编写翻译时将函数体嵌入在每三个调用途。编写翻译时,相像宏替换,使用函数体替换调用途的函数名。常常在代码中用inline修饰,可是能或不可能产生内联函数,需求看编写翻译器对该函数概念的切实管理

  • noinline 不内联
  • always_inline 总是内联
  • 那四个都以用在函数上

内联的实质是用代码块间接调换掉函数调用场,好处是:快代码的实施,缩短系统花费.适用处景:

  • 这几个函数更加小
  • 以此函数不被日常调用

应用例子:

//函数声明
void test(int a) __attribute__((always_inline));

int XNAME(2) = 20; // becomes int x2 = 20;

extern "C" {
    // Let's assume that this expands to `fn foo();`.
    #[my_identity_macro]
    fn foo();
}

天性关联
有少数很要紧,便是你不用须要领会如何属性适用于怎样对象和聚合。有三个特别的函数对于确定保证你的代码能够在运行时妥贴管理属性和措施的举行:(vlax-property-available-pState of Qatar和(vlax-method-applicable-p卡塔尔国。那七个函数只是三个Visual
LISP决断函数,它提供布尔测量检验剖断标准是真或假(LISP术语为non-nil或nil)。

warn_unused_result

当函数也许措施的重回值相当重大时,供给调用者必得检查或然接收重回值,不然编译器会时有产生警告提醒

- (BOOL)availiable __attribute__((warn_unused_result))
{
   return 10;
}

告诫如下:

图片 4

Paste_Image.png

PRINT_XN(1);        // becomes printf(“x1 = %d\n”, x1);

  • 在 procedural
    macros 中生成 macro_rules! items

那几个函数的语法如下:
(vlax-property-available-p object property) 
(vlax-method-applicable-p object method) 

objc_subclassing_restricted

因为某个原因,大家不期望这一个类被接续,也正是 “最终”的类,用法如下:

__attribute__((objc_subclassing_restricted))
@interface ViewController : UIViewController


@end

借使一连了那么些类,编写翻译器会报错

图片 5

Paste_Image.png

PRINT_XN(2);        // becomes printf(“x2 = %d\n”, x2);

目前,函数式(mac!())和属性(#[mac])macros
都得以转移macro_rules!项目。

质量是跟与之提到的对象的品种相关。譬如,一个Circle(圆State of Qatar对象有一个Diameter(直径卡塔尔(قطر‎属性,但Line
(线State of Qatar对象就平昔不。依据分化的对象类型,属性也各不等同,下边包车型大巴代码在拾取CIRCLE(圆State of Qatar图元时会出错:

objc_requires_super

其一性子必要子类在重写父类的法猪时,应当要重载父类方法,也正是调用super方法,不然警报.示比方下:

@interface ViewController : UIViewController

- (void)jump __attribute__((objc_requires_super));

@end

- (void)jump{
    NSLog(@"父类必须先执行");
}


@interface SGViewController : ViewController

@end

@implementation SGViewController
- (void)jump{
    NSLog(@"子类才能再执行");
}
@end

告诫如下:

图片 6

Paste_Image.png

    return 0;

  • The $m:meta 匹配器支持 arbitrary
    token-stream
    values.

(if (setq ent (entsel
“\n接收对象以博得其性质: “卡塔尔国卡塔尔(قطر‎
  (progn
    (setq obj (vlax-ename->vla-object (car ent)))
    (princ
      (strcat “\n长度: ” (vla-get-Length obj))
    )
  )
)

objc_boxable

得以达成相近于NSNumber
的立即打包本事@(…卡塔尔国,平常对于struct,union大家不能不通过NSValue将其打包.
objc_boxable 能够扶植大家完结高效打包,示比方下:

//自定义结构体
typedef struct __attribute__((objc_boxable)){
    CGFloat x,y,width,height;
}SGRect;

 SGRect rect = {0,0,100,200};
 //这里直接打包成NSValue
 NSValue *value = @(rect);

 //这里我直接用系统的方法打印
 NSLog(@"%@",NSStringFromCGRect(value.CGRectValue));

 输出:
 2016-07-21 21:28:43.538 Study[14118:5408921] {{0, 0}, {100, 200}}

那般SGRect就持有快速打包功效了.

}

也正是说,以下内容今后有效:

而是,要是在取对象的本性前先检查该属性是否行得通时,代码的施行就会健康,如上边包车型地铁例证所示:

constructor / destructor

意思是:
构造器和析构器;constructor修饰的函数会在main函数在此以前实践,destructor修饰的函数会在程序exit前调用.
自己要作为表率服从规则如下:

int main(int argc, char * argv[]) {
    @autoreleasepool {
        NSLog(@"main");
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

__attribute__((constructor))
void  before(){
    NSLog(@"before main");
}

__attribute__((destructor))
void  after(){
    NSLog(@"after main");
}

//在viewController中调用exit
- (void)viewDidLoad {
    [super viewDidLoad];

    exit(0);
}
输出如下:

2016-07-21 21:49:17.446 Study[14162:5415982] before main
2016-07-21 21:49:17.447 Study[14162:5415982] main
2016-07-21 21:49:17.534 Study[14162:5415982] after main

注意点:

  • 次第退出的时候才会调用after函数,经测试,手动退出程序会奉行
  • 下边多少个函数不管写在哪个类里,哪个文件中作用都未有差距
  • 一经存在多个修饰的函数,那么都会实行,顺序不定

实在如若存在七个修饰过的函数,能够它们的调治优先级
代码如下:

int main(int argc, char * argv[]) {
    @autoreleasepool {
        NSLog(@"main");
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

__attribute__((constructor(101)))
void  before1(){
    NSLog(@"before main - 1");
}
__attribute__((constructor(102)))
void  before2(){
    NSLog(@"before main - 2");
}

__attribute__((destructor(201)))
void  after1(){
    NSLog(@"after main - 1");
}
__attribute__((destructor(202)))
void  after2(){
    NSLog(@"after main - 2");
}

输出结果如下:
2016-07-21 21:59:35.622 Study[14171:5418393] before main - 1
2016-07-21 21:59:35.624 Study[14171:5418393] before main - 2
2016-07-21 21:59:35.624 Study[14171:5418393] main
2016-07-21 21:59:35.704 Study[14171:5418393] after main - 2
2016-07-21 21:59:35.704 Study[14171:5418393] after main - 1

注意点:

  • 括号内的值表示优先级,[0,100]其一重返时系统一保险留的,本身千万别调用.
  • 依赖输出结果可以看见,main函数从前的,数值越小,越先调用;main函数之后的数值越大,越先调用.

当函数注脚和函数达成分开写时,格式如下:

static void before() __attribute__((constructor));

static void before() {
    printf("before\n");
}

商讨:+load,constructor,main的施行顺序,代码如下:

+ (void)load{
    NSLog(@"load");
}
__attribute__((constructor))
void  before(){
    NSLog(@"before main");
}

输出结果如下:
2016-07-21 22:13:58.591 Study[14185:5421811] load
2016-07-21 22:13:58.592 Study[14185:5421811] before main
2016-07-21 22:13:58.592 Study[14185:5421811] main

能够看来实行种种为:
load->constructor->main
干什么呢?
因为 dyld(动态链接器,程序的开始的一段时代起源)在加载 image(能够通晓成 Mach-O
文件)时会先文告 objc runtime 去加载此中具备的类,每加载一个类时,它的
+load 随之调用,全部加载成功后,dyld 才会调用那几个 image 中全体的
constructor 方法,然后才调用main函数.

Here’s the output:

macro_rules! accept_meta { ($m:meta) => {} }
accept_meta!( my::path );
accept_meta!( my::path = "lit" );
accept_meta!( my::path ( a b c ) );
accept_meta!( my::path [ a b c ] );
accept_meta!( my::path { a b c } );

(if (setq ent (entsel
“\n选取对象以博取其性质: “State of QatarState of Qatar
  (progn
    (setq obj (vlax-ename->vla-object (car ent)))
    (if (vlax-property-available-p obj ‘Length)
      (princ
        (strcat “\n长度: ” (vla-get-Length obj))
      )
      (princ “\n对象未有 LENGTH 属性…”卡塔尔
    )
  )
)

enable_if

用来检查参数是不是合法,只可以用来修饰函数:

void printAge(int age)
__attribute__((enable_if(age > 0  && age < 120, "你丫太监?")))
{
    NSLog(@"%d",age);
}

代表只好输入的参数只可以是 0 ~ 120左右,不然编写翻译报错
报错如下:

图片 7

Paste_Image.png

x1 = 14

典型库中扩大的 const fn

噩运的是,没有一向的不二秘技得到给定对象的具有属性的列表来用于遍历编制程序。然而,你要么得以拿走列表消息的,那样对你的扶助也不算小。

cleanup

宣示到叁个变量上,当以此变量功效域截至时,调用钦点的叁个函数.如若不驾驭怎么是成效域,请先读书一下.事例:

//这里传递的参数是变量的地址
void intCleanup(int *num){
    NSLog(@"cleanup------%d",*num);
}

- (void)test{
  int a __attribute__((cleanup(intCleanup))) = 10;
}

输出结果为:
2016-07-22 09:59:09.139 Study[14293:5495713] cleanup------10

注意点:

  • 点名的函数字传送递的参数是变量的地址
  • 功能域的终止包罗:大括号截至、return、goto、break、exception等气象
  • 用功能域内有三个cleanup的变量时,遵循 先入后出 的栈式布局.

亲自过问代码:

void intCleanup(int *num){
    NSLog(@"cleanup------%d",*num);
}

void stringCleanup(NSString **str){
    NSLog(@"cleanup------%@",*str);
}

void rectCleanup(CGRect *rect){
    CGRect temp = *rect;
    NSString *str = NSStringFromCGRect(temp);
    NSLog(@"cleanup------%@",str);
}


 int a __attribute__((cleanup(intCleanup))) = 10;
    {
        NSString *string __attribute__((cleanup(stringCleanup))) = @"string";
        CGRect rect __attribute__((cleanup(rectCleanup))) = {0,0,1,1};
    }


    输出结果为:
    2016-07-22 10:09:36.621 Study[14308:5498861] cleanup------{{0, 0}, {1, 1}}
2016-07-22 10:09:36.622 Study[14308:5498861] cleanup------string
2016-07-22 10:09:36.622 Study[14308:5498861] cleanup------10

评论:假设修饰了有些对象,那么cleanup和dealloc,何人先实行?
测量检验代码如下:

void objectCleanup(NSObject **obj){
    NSLog(@"cleanup------%@",*obj);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    ViewController *vc __attribute__((cleanup(objectCleanup))) = [[ViewController alloc] init];
}

- (void)dealloc{
    NSLog(@"dealloc");
}

输出结果如下:
2016-07-22 10:23:08.839 Study[14319:5502769] cleanup------<ViewController: 0x13fe881e0>
2016-07-22 10:23:08.840 Study[14319:5502769] dealloc

可以明显看出,cleanup先于对象的dealloc试行.

  • 在block中的用法:在block中选用,先看例子:

//指向block的指针,觉得不好理解可以用typeof
void blockCleanUp(void(^*block)()){
    (*block)();
}

 void (^block)(void) __attribute__((cleanup(blockCleanUp))) = ^{
        NSLog(@"finish block");
    };

以此利润便是,不用等到block最终才写一些代码,我们能够把它投身block的自由地点,幸免忘记.

x2 = 20

此版本中,以下函数成为const fn

要查询在加以的指标上有啥性质和格局,可在该指标上选拔(vlax-dump-object卡塔尔函数。函数的语法是(vlax-dump-object object
show-methodsState of Qatar, show-methods参数能够是nil或非nil。要是是非nil,就体现对象援助的秘籍,不然就不出示情势。

overloadable

用来c语言函数,能够定义若干个函数名相仿,但参数差异的方法,调用时编译器会自动依照参数接纳函数原型:

__attribute__((overloadable)) void print(NSString *string){
    NSLog(@"%@",string);
}

__attribute__((overloadable)) void print(int num){
    NSLog(@"%d",num);
}

//调用
print(10);
print(@"哈哈");

Note how the PRINT_XN() macro uses the # operator to combine strings
and the ## operator to combine tokens into a new identifier.

  • is_power_of_two用于无符号整数

图 3-2 – Documents集合的属性和措施 

objc_runtime_name

看看runtime是否就以为高大上,没有错这么些也跟运转时有关.功用是将将类或协商的名字在编写翻译时内定成另二个.示举例下:

__attribute__((objc_runtime_name("NSObject")))
@interface SGObject :NSObject

@end

 //调用
 NSLog(@"%@",[SGObject class]);
 //输出
 2016-07-22 11:18:00.934 Study[14355:5516261] NSObject

能够用来做代码混淆.

愈来愈多请看官方网站:
https://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html

 

追加到规范库的函数

图3-2展现了Documents集结对象的习性和章程。你可以预知到输出的首先行突显了蕴藏三个呈报的此中对象参照(IAcadDocuments卡塔尔国,并且列出了可用的品质和方式。

2.Variadic Macros: … and _ _VA_ARGS_ _

以下函数和宏已经牢固:

提示! 以下的吩咐定义对展现所选图元的习性和方法会有用场。它从不提供出错管理,不过它仍然为个有效的小工具。

Some functions, such as printf(), accept a variable number of arguments.
The stdvar.h header file,provides tools for creating user-defined
functions with a variable number of arguments. And C99 does the same
thing for macros.Although not used in the standard, the word variadic
has come into currency to label this facility. (However, the process
that has added stringizing and variadic to the C vocabulary has not yet
led to labeling functions or macros with a fixed number of arguments as
fixadic functions and normadic macros.)

  • todo!()

  • slice::repeat

  • mem::take

  • BTreeMap::get_key_value 和 HashMap::get_key_value

  • Option::as_deref, Option::as_deref_mut

  • Option::flatten

  • UdpSocket::peer_addr

  • {f32,f64}::to_be_bytes{f32,f64}::to_le_bytes{f32,f64}::to_ne_bytes{f32,f64}::from_be_bytes{f32,f64}::from_le_bytes,和{f32,f64}::from_ne_bytes

(defun C:DUMP (/ ent obj)
  (while (setq ent (entsel “\n选拔图元以赢得对象数据: “卡塔尔国卡塔尔(قطر‎
    (setq obj (vlax-ename->vla-object (car ent)))
    (vlax-dump-object obj T)
    (vlax-release-object obj)
  )
  (princ)
)

The idea is that the final argument in an argument list for a macro
definition can be ellipses (that is, three periods)(省略号). If so,
the predefined macro _ _VA_ARGS_ _ can be used in the substitution
part to indicate what will be substituted for the ellipses. For example,
consider this definition:

端详可查阅更新表明:

提示! 属性前面包车型地铁括号(RO卡塔尔国代表该属性为只读,在此,全部的性质均为只读,方法后边括号内的数字代表了每一措施所供给的参数数目。

#define PR(…) printf(_ _VA_ARGS_ _)

要拜候属性,可利用(vla-get-xxx卡塔尔国函数,或更通用的(vlax-get-Property卡塔尔(قطر‎函数,两个都足以。第三个函数的语法是(vla-get-xxx
object卡塔尔(قطر‎,此中XXX是属性名。在使用(vlax-get-propertyState of Qatar函数时,语法为(vlax-get-property object
propertyname卡塔尔国,个中propertyname能够是双引号字符串或单引号字符串。

Suppose you later invoke the macro like this:

(文/开源中夏族民共和国卡塔尔国    

(vlax-get-property object property) 或 
(vla-get-property object) 或 
(vlax-get object property) 

PR(“Howdy”);

再次回到值是分配给该对象的钦点名称属性的值,假使该目的的钦点属性不设有,就能发出错误。举个例子来讲,如若您对Line(直线卡塔尔国图元查询“Diameter”(直径卡塔尔属性,就能够时有产生错误。

PR(“weight = %d, shipping = $%.2f\n”, wt, sp);

参数: 
Object – 一个 vla-对象 
Property – 与指标相关的有效属性。 

For the first invocation, _ _VA_ARGS_ _ expands to one argument:

示例: 
(vlax-get-property objLine “Length”) 
(vlax-get-property objLine ‘Length) 
(vla-get-Length objLine) 

“Howdy”

全数这几个话语都将做到同样的业务。

For the second invocation, it expands to three arguments:

性能的名号并不须求分别轻重缓急写,但本书的例子都将首字母大写,以示清晰。简单来说,你会意识上述前两项都很好用,但也可以有情状是必要用到后两项。极度是关联到象Microsoft  Excel
或 Word那样的外表应用程序。第八种方法 vlax-get 是卡宴14版遗留下来的,只为了向后非凡而已。

“weight = %d, shipping = $%.2f\n”, wt, sp

运用办法
经过图3-2的例证,你可观看Documents集结对象协理4种艺术:Add、Close、Item和Open。Item方法须求利用多个参数(也正是在图3-第22中学体现在情势前边的相当(1卡塔尔卡塔尔(قطر‎,它是由会集所引出的文档的目录和命名。

Thus, the resulting code is this:

平凡Item方法有贰个有意思的性状,那正是它能够选择字符串或整数值参数。当给的是整数参数时,它就回顾地再次回到集合的第(nth卡塔尔国条约,0为率先条约。当给的是三个字符串值时,它尝试通过它的称号属性来获取条目款项。Item
(名称卡塔尔方法不分大小写,那是一对一有效的,它不需求先对字符串举办高低写调换就可以担当名称。

printf(“Howdy”);

提示! 假如您熟谙Visual
Basic或VBA并时时应用默许方法和默许属性,那你要注意,这种天性在Visual
LISP是不设有的。譬喻,在Visual Basic中,通过以下任性一种路子来拜望Item方法都以低价的:
Object.Item(12) 或 Object(12) 或
Object(“Name”) 

printf(“weight = %d, shipping = $%.2f\n”, wt, sp);

那是因为在VB或VBA中,Item方法是绝大大多指标的暗许方法。Visual
LISP并不帮助这种性子,它需求在历次使用时都注解全体属性和措施。举例:

Listing 2 shows a slightly more ambitious example that uses string
concatenation and the # operator:

(vlax-invoke-method documents “Item”
12卡塔尔 会有效应… 
(vla-item documents
“Drawing1.dwg”卡塔尔 会有机能… 
(vlax-invoke-method documents
12卡塔尔国 不会有成效。 

 

动用图3-2的例子,Item方法可因此以下任何格局运用:

// variadic.c — variadic macros

(vla-Item documents 1) 
(vla-Item documents “Drawing1.dwg”) 
(vlax-invoke-method documents “Item” 1) 
(vlax-invoke-method documents ‘Item “Drawing1.dwg”) 

#include <stdio.h>

(vlax-invoke-method object method [arguments]…) 或 
(vla-method object arguments) 或 
(vlax-invoke object method [arguments] …) 

#include <math.h>

调用关联于对象的主意并为方法提供任何所需的参数。如若成功,将赶回结果。假使目的未有提供相应的措施,将会生出ActiveX错误。比方,在Text(文本卡塔尔图元中调用“Offset”(偏移卡塔尔方法,将会发生ActiveX错误。

#define PR(X, …) printf(“Message” #X “: ” _ _VA_ARGS_ _)

参数: 
Object – 一个vla-对象 
Method – 由对象露出的办法 
Arguments – 扶持该形式的别样所需的参数 

int main(void)

示例: 
(vlax-invoke-method objLine “Move” point1
point2) 
(vla-Move objLine point1 point2) 
(vlax-invoke objLine “Move” point1 point2) 

{

持有那一个示例做的专业都大同小异。对于大繁多AutoCAD对象的话都以卓有功效的,但对此由TypeLib接口或外界应用程序或ActiveX组件输入创造的对象则不都使得。你能够将率先种办法用于外界应用程序对象,而得以将第二种艺术用于内部对象。第二种情势是为了福特Explorer14的向后非常。

    double x = 48;

提示! 当你选拔对质量和形式用Get或Put中的大肆一种样式时,你会发觉用较长的款式(如vlax-put-property卡塔尔国比用超短的款式(如vla-put-color卡塔尔更加灵活。原因是透过从函数中分别出属性名称,你就足以定义函数和循环语句,它们能够选取八性子质列表及有关的数值,比方…

    double y;

(defun MapPropertyList (object proplist)
  (foreach propset proplist
    (if (vlax-property-available-p object (car propset))
      (vlax-put-property object (car propset) (cadr propset))
    )
  )
)

    y = sqrt(x);

当试图在措施上行使这种艺术时要特地小心,因为方法的参数列表会趁机对象和方法的扭转而调换。有部分办法无需参数,而另一些则随长度变化。

    PR(1, “x = %g\n”, x);

数据类型

    PR(2, “x = %.2f, y = %.4f\n”, x, y);

数据类型是用于描述给定对象或质量可含蓄的数值的门类。数据类型的例子有整数、双精度、货币、日期、字符串等等。在AutoLISP已经享受“类型非亲非故”多年后,Visual
LISP也长久以来能够,但不光只那样。在AutoCAD里,你能够尽量地通过AutoLISP来保留那体系型非亲非故,但当提到任何应用程序时,比方Microsoft
Excel,你将不可幸免并且精明地用到数据类型。

    return 0;

品种非亲非故并不是免费午饭,其代价是成效低下。当您提前评释了数据类型,你就通告编写翻译器调动仅仅够用的财富来同盟预订数据。举例,存款和储蓄整数类型的数额远比存款和储蓄“长”数据值要低得多。当您未使用数据类型时,全体数据都会活动分配尽或者长的数据类型,以确定保障能合营全数相当的大可能率现身的数据。其结果导致应用程序消耗的能源远比它的要求大得多,无论是从初步加载的尺寸或者其运作时刻财富的分红。

}

那便是为何程序开拓的言语中,象C++、Java,以至是Visual
Basic平常都以超级快的(相比较使用自由类型语言编制程序的相像效果卡塔尔国。他们确定保证能提前简洁明了管理以作保运营时有更加快的性质。AutoLISP并不这么做,由此是相对慢的拍卖语言。而Visual
LISP绝对会快一些,但唯有您选用其新的特色,让其最尽恐怕发挥。

In the first macro call, X has the value 1, so #X becomes “1”. That
makes the expansion look like this:

常量和枚举
常量是特种的数据类型。正如其名,它的值是不行修正的。不常被称为静态。日常来讲,常量是由程序语言或由托管应用程序本身提供,作为一种方便人民群众的手法。举个例子,acByLayer常量在属性值中得以被256代替。名称值比整数值越来越好明白也越来越好记。例如,以下多个语句在成效上实属一致的。

(#为参数加双引号。)

(vla-put-color object acByLayer) 
(vla-put-color object 256) 

print(“Message ” “1” “: ” “x = %g\n”, x);

枚举是常量的逻辑组合,它用来规定常量值范围。举例你能够用颜色值1、2、3、4、5,但也能够将之常量化为acRed、acYellow、acGreen、acCyan、acBlue、acMagenta和acWhite,那样更分明。这类别型的连带常量值范围即称为枚举。参看附录A为标准的AutoCAD枚举清单。

Then the four strings are concatenated, reducing the call to this:

提醒!并非有着的ActiveX枚举都在Visual
LISP中有提供。举例,标准的Decimal(十进制卡塔尔国或Short(短卡塔尔国数据类型并不曾镜像为vlax-vbDecimal或vlax-vbShort。请参阅第六章学习越来越多关于数据类型的新闻。

print(“Message 1: x = %g\n”, x);

变体和阳泉数组
在上节的数据类型中,有关联对轻松类型注明使用最大的可用分配的定额,举例在AutoLISP中的(setqState of Qatar语句。事实上,是分配了三个变体数据类型,变体满含全部的数据类型,它提供了足足的财富空间去蕴涵其余此外数据类型,能够是数值、日期、字符串或别的。事实上,变体数据类型是ActiveX产生出来的。但以此概念更具备常常性,在ActiveX以前已经存在不短的年月。

Here’s the output:

实则Visual
LISP满含了将具有ActiveX数据转变为包罗提醒满含哪种品种的区分符的变体。认为有一点乱,但真实意况很简短。该容器是二个带有有货币数据类型值的变体,当您分配给目的贰个新值时,你必需提供区分符以使得那个数据可以预知科学积存。那是必需求做的,特别是你在AutoCAD和别的应用程序(如Microsoft
ExcelState of Qatar之间传递数值时。

Message 1: x = 48

除开垦送数值外,你还足以从变体值中询问嵌套的数据类型,也可将值不易的转换成为相关的LISP数据类型。举例,你可查询变体对象值是还是不是含有了双精度值。然后你能够在LISP上将以此数值读取为实数(REALState of Qatar数据类型。Visual
LISP提供了大气的函数用于在LISP情形中创设、读取、改正变体量数据值。

Message 2: x = 48.00, y = 6.9282

云浮数组也就是AutoLISP中的LIST对象。首要的分别在于它是静态的。意思就是说他不大概基于他们能积累的数字的轻微来加长或改换项数。那将制止了在总括分配或取得超越数主任度的成分时发出的不须求的荒谬。那正是它们之所以被叫做“安全”的案由。任何传递到ActiveX的LIST构造必需先转变来安全体组。任何从ActiveX对象得到的LIST面向对象的数量都必得通过象(carState of Qatar、(nth卡塔尔国、(accoc卡塔尔、(mapcarState of Qatar、(member卡塔尔国等的LISP函数调换来LIST数据类型。Visual
LISP为成立操作、阅读安全部组数据值提供了多量的效用。

Don’t forget, the ellipses have to be the last macro argument:

越来越多关于变体和安全体组的剧情,请参阅第六章。

#define WRONG(X, …, Y) #X #_ _VA_ARGS_ _
#y(这几个是漏洞非常多的例子。)

取名空间
取名空间是分配用于周转进程的虚构空间,它与空间中的其它财富相互同盟。但它有的时候也足以和任何命名空间中的别的进程相挂钩。可以把命名空间想象成主卧。你的应用程序就好像在寝室专业的人,也即在特定命名空间的经过。此外的应用程序宛如在面前遇到次卧(命名空间State of Qatar专门的学业的大同小异,这五个人得以互相独立和隔开的,但她俩也足以并行传递数据以便调换。那正是命名空间工作的法则。

 

应用命名空间的补益在于能够在特定的命名空间中的进度与其余命名空间相独立的,那样能够在它们中间不相互破坏(如在斗争保存能源时State of Qatar。它们也可径直通过它们的命名空间加载和卸载进度。换句话说,这有一点象拆掉房子里一间主卧,而屋家就疑似模块化格局建的一律。移去二个房间不会潜移暗化到其余房间或进度的活着。

 

可能应用命名空间最大的劣点是会以致在操作系统或其宿主应用程序上的有的付出。为了管住好给定的命名空间,它必得有投机的内部存款和储蓄器地址范围和指针分配。那亟需消耗额外的能源去追踪和垄断(monopoly卡塔尔命名空间,这反过来又在须要时提供了第一手的措施去做客它、卸载它或行车制动器踏板它。

 

AutoCAD提供了在Visual
LISP内部对命名空间的内处方法,类似在ObjectA讴歌RDXX和VBA中也足以。那是Visual
LISP比AutoLISP效能强盛改正的又一表现。实际上种种张开的文书档案都以其和好的命名空间(纵然您不是在单文件情势下专门的学业的话State of Qatar,当在叁个图纸中设置贰个变量而又希图在另二个图形中读取它时,这么些影响就能够看出。是有方法能够兑今后这个图片中传送变量的,大家第十章将构和到。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图