当前位置: 首页 > news >正文

工信部网站验证码创建网站的流程是什么

工信部网站验证码,创建网站的流程是什么,做深度报道的网站,海口做网站优化目录 ARC规则 规则 对象型变量不能作为C语言结构体的成员 显式转换id和void* 属性 数组 ARC规则 规则 在ARC有效的情况下编译源代码必须遵守一定的规则: 主要解释一下最后两条 对象型变量不能作为C语言结构体的成员 要把对象型变量加入到结构体成员中时&a…

目录

ARC规则

规则

对象型变量不能作为C语言结构体的成员

显式转换id和void*

属性

数组


ARC规则

规则

在ARC有效的情况下编译源代码必须遵守一定的规则:

主要解释一下最后两条

对象型变量不能作为C语言结构体的成员

要把对象型变量加入到结构体成员中时,可强制转换为void*或是附加前面所述的__unsafe_unretained修饰符。

显式转换id和void*

ARC无效时,像以下代码这样将id变量强制转换void*变量并不会出问题。

id obj = [[NSObejct alloc] init];
void *p = obj;

更进一步,将该void*变量赋值给id变量中,调用其实例方法,运行时也不会有问题

id o = p;
[o release];

但是在ARC有效时这便会引起编译错误。

id型或对象型变量赋值给void*或者逆向赋值时都需要进行特定的转换。如果只想单纯地赋值,则可以使用"__bridge转换"。

id obj = [[NSObject alloc] init];
void *p = (__bridge void *)obj;
id o = (__bridge id)p;

像这样,通过"__bridge转换",id和void*就能互相转换。

但是转换为void* 的__bridge转换,其安全性与赋值给__unsafe_unretained修饰符相近,甚至会更低。如果管理时不注意赋值对象的所有者,就会因悬垂指针而导致程序崩溃。

__bridge转换中还有另外两种转换,分别是“__bridge_retained转换”和"__bridge_transfer转换"

id obj = [[NSObject alloc] init];
void *p = (__bridge_retained void *)obj;

__bridge_retained转换可使要转换赋值的变量也持有所赋值的对象。下面来看看ARC无效时的源代码是如何编写的

id obj = [[NSObject alloc] init];
void *p = obj;
[(id)p retain];

__bridge_retained转换变为了retain。变量obj和变量p同时持有对象。再来看几个其他的例子。

void *p = 0;
{id obj = [[NSObject alloc] init];p = (__bridge_retained void *)obj;
}
NSLog(@"class=%@", [(__bridge id)p class]);

变量作用域结束时,虽然随着持有强引用的变量obj失效,对象随之释放,但由于__bridge_retained转换使变量p看上去处于持有该对象的状态,因此该对象不会被废弃。下面我们比较一下ARC无效时的代码

void *p = 0;
​
{id obj = [[NSObject alloc] init];//[obj retainCount] -> 1p = [obj retain];//[obj retainCount] -> 2[obj release];//[obj retainCount] ->1
}
//[(id)p retainCount] -> 1
//即 [obj retainCount] -> 1
//对象仍存在
NSLog(@"class=%@", [(__bridge id)p class]);

__bridge_transfer转换提供与此相反的动作,被转换的变量所持有的对象在该变量被赋值给转换目标变量后随之释放。

id obj = (__bridge_transfer id)p;

该源代码在ARC无效时这样表述:

id obj = (id)p;
[obj retain];
[(id)p release];

__bridge_retained转换与retain类似,__bridge_transfer转换与release相似。在给id obj赋值时retain即相当于__strong修饰符的变量。

如果使用以上两种转换,那么不使用id型或对象型变量也可以生成、持有以及释放对象。虽然可以这样做,但是在ARC中不推荐这种方法

void *p = (__bridge_retained void *)[[NSObject alloc] init];
NSLog(@"class=%@", [(__bridge id)p class]);
(void)(__bridge_transfer id)p;

该源代码与ARC无效时的下列源代码相同

//ARC无效
id p = [[NSObject alloc] init];
NSLog(@"class=%@", [p class]);
[p release];

这些转换多用于OC对象与CF对象之间的相互变换中。

OC对象和CF对象的区别很小,不同之处仅仅只在于生成对象的框架不同。可以使用免费桥来实现二者之间的转换("Toll—Free Bridge",这种转换不用使用额外的CPU资源)。

以下函数即Toll—Free Bridge转换的函数,可用于OC对象和CF对象之间的相互变换,即Toll—Free Bridge转换。

属性

当ARC有效时,OC类的属性也会发生变化。

以上各种属性赋值给指定的属性中就相当于赋值给附加各属性对应的所有权修饰符的变量中。只有copy属性不是简单的赋值,它赋值的是通过NSCopying接口的copyWithZone:方法复制赋值源所生成的对象。

并且,在声明类成员变量时,如果同属性声明中的属性不一致则会引起编译错误。比如下面这种情况。

id obj;
@property (nonatomic, weak)id obj;

在声明id型obj成员变量时,定义属性声明为weak,编译器报错。

此时,需要在成员变量的声明中附加__weak修饰符或者使用strong属性来替代weak属性。

数组

将变量作为静态数组使用时,附有__strong,__weak,__autoreleasing修饰符的数组可以在初始化时初始化为nil。

而对于动态数组,NSMutableArray、NSMutableDicitionary、MSMutableSet等容器会恰当地持有追加的对象并为我们管理这些对象。

像这样使用容器虽然更为合适,但在C语言的动态数组中也可以使用附有__strong修饰符的变量,但是要遵守一些事项:

声明动态数组用指针

id __strong *array = nil;

id *类型默认为"id __autoreleasing*类型",所以要显式指定修饰符__strong。并且,附有__strong只保证id型变量被初始化为nil,并不保证附有__strong修饰符的id指针型变量被初始化为nil。

使用类名时如下记述:

NSObject * __strong *array = nil;

其次使用calloc函数确保想分配的附有__strong修饰符变量的容量占有的内存块。

array = (id __strong *)calloc(entries, sizeof(id));

该源代码分配了entries个所需的内存块。由于使用附有__strong修饰符的变量前必须先将其初始化为nil,所以这里使用使分配区域初始化为0的calloc函数来分配内存。不使用calloc函数,在用malloc函数分配内存后可用memset等函数将内存填充为0。

但是,像下面的源代码这样,将nil代入到malloc函数所分配的数组各元素中来初始化是非常危险的。

array = (id __strong *)malloc(sizeof(id) * entries);
for (NSUInteger i = 0; i < entries; ++i)array[i] = nil;

这是因为由malloc函数分配的内存区域没有被初始化为0,因此nil会被赋值给附有__strong修饰符的并被赋值了随机地址的变量中,从而释放一个不存在的对象。在分配内存时推荐使用calloc函数。

像这样,通过calloc函数分配的动态数组就能完全像静态数组一样使用。

array[0] = [[NSObject alloc]];

但是,在动态数组中操作附有__strong修饰符的变量与静态数组有很大差异,需要自己释放所有的元素。在只是简单地使用free函数废弃了数组用内存块的情况下,数组各元素所赋值的对象不能被再次释放,从而引起内存泄漏。这是因为在静态数组中,编译器能根据变量作用域自动插入释放赋值对象的代码,而在动态数组中,编译器不能确定数组的生存周期,所以无从处理。

使用动态数组时,一定要将nil赋值给所有元素中,使得元素所赋值对象的强引用失效,从而释放那些对象。在此之后,使用free函数废弃内存块。

for (NSUInteger i = 0; i < entries; ++i) array[i] = nil;
free(array);

同初始化的注意事项相反,即使用memset等函数将内存填充为0也不会释放所赋值的对象。这非常危险,只会引起内存泄漏。对于编译器,必须明确地使用赋值给附有__strong修饰符变量的源代码。所以请注意,必须将nil赋值给所有数组元素。

并且,memcpy和realloc函数也会有危险,因为数组元素所赋值的对象有可能被保留在内存中或是重复被废弃,所以也禁止使用。

http://www.khdw.cn/news/66329.html

相关文章:

  • 长沙营销型网站建设制作公司网站费用
  • wordpress 首页添加链接地址seo关键词怎么选
  • wordpress博客入门西安seo搜推宝
  • 网站接入服务商是什么中国销售网
  • 做的好的宠物食品网站抖音信息流广告怎么投放
  • flash企业网站模板php线下推广方法及策略
  • 做网站一年赚80亿东莞网站建设做网站
  • 做网站实训心得成都百度百科
  • 网络公司做机场网站桂林网站设计制作
  • 购物网站建设 成都数据分析师报考条件
  • 做网站要多少钱汉狮seo收索引擎优化
  • 上海网站建设优化祁阳seo
  • 西宁高端网站建设公司网站流量统计平台
  • 网站建站的作用百度指数官网查询入口
  • 做淘宝要用到哪些网站seo的主要分析工具
  • 在中国备案的网站服务器sem百度竞价推广
  • 采购网站大全网络市场的四大特点
  • 微网站是官网的手机站龙岗网站推广
  • 兰溪网站建设百度工具seo
  • wordpress增加额外链接官网seo哪家公司好
  • 免费b站推广网站2023设计网站大全
  • 做党建需要关注网站网站推广计划方案
  • 聊城哪里网站做的好软文平台
  • 奥创微信管理系统网络推广seo怎么做
  • 上海公司注册信息查询网seo入门书籍推荐
  • 如何做网站引流网络推广与营销
  • 阿里巴巴做网站多少钱深圳网络运营推广公司
  • 商丘网站制作推广网站app开发公司
  • w5500做服务器网站在哪个平台做推广比较好
  • 江诗丹顿手表网站网页加速器