OC基础语法(六)---内存管理(二)



一、ARC

简介:ARC是自ios 5 之后增加的新特性,完全消除了手动管理内存的繁琐,编译器会自动在适当的地方插入retain、release、autorelease语句。你完全不需要担心内存,因为编译器为你处理了一切。

ARC 是编译器特性吗,而不是ios运行时的特性,它也不是类似于其他语言中的垃圾收集器。因为ARC 和手动内存管理性能是一样的,有时还能更加快速,因为编译器还可以执行某些优化

ARC判断准则:只要没有强指针指向的对象,就会释放对象。

指针分两种:

1.强指针:默认所有实例变量和局部变量都是Strong指针;

2.弱指针指向的对象被回收后,弱指针会自动变为nil指针,不会引发野指针

          错误

ARC特点:

1.不能调用release、retain、autorelease、retainCount

2.可以重写dealloc,但是不能调用[super dealloc]

3.@property参数:

  *strong:成员变量是强指针(适用于OC对象);

  *weak:成员变量是弱指针(适用于OC对象);

  *assign:适用于非OC对象类型;

4.以前的retain改为strong。

    ARC循环引用解决方案:一端用strong;一端用weak。     

二、Block

作用:用来保存一段代码。苹果官方建议尽量多用block。在多线程、异步

      任务、集合遍历、集合排序、动画转场用的很多。

block标志: ^ .

block和函数很相像:

1.可以保存代码;

2.有返回值;

3.有形式参数;

4.调用方法一样。

注:block还可以作为函数参数或者函数的返回值。

block定义:

int (^MySum)(int, int) = ^(int a, int b

{

       return a+b;

     };

     定义了一个MySumblocks对象,它带有两个int参数,返回int。等式右边就是blocks的具体实现.

调用block: int c = MySum(10,11);

    Block可以访问局部变量,但是不能修改。

    int sum 10;

   int (^MyBlock)(int) = ^(int num) 

   {

                sum++;//编译报错

                return num * sum;

    };

    如果要修改就要加关键字:__block

     __block int sum 10;

Block和指向函数的指针的比较:

    1.定义函数指针:

    int (*myFn)();

     定义Block

    int (^MyBlocks)(int,int);

    2.调用函数指针:

    (*myFn)(10, 20);

      调用Block

    MyBlocks(10, 20);

使用typedef定义block类型:(参考typedef指向函数的指针)

(1)typedef int(^MyBlock)(int,int);

MyBlock sumBlock = ^(int a,int b)

{  return a+b; };

(2)MyBlock minusBlock;

       minusBlock = ^(int a,int b) 

      {  return a-b;  };

三、protocol(协议)

基本用途:

1.可以用来声明一大堆方法(不能声明成员变量);

2.只要某个类遵守了这个协议,就相当于拥有这个协议中所有的方法声明;

3.只要父类遵守了某个协议,就相当于子类也遵守了。

 

协议的声明类似于类接口的声明,有一点不同的是,协议没有父类,并且不能定义成员变量

下面的例子演示了只有一个方法的协议的声明:

@protocol MyProtocol

//@required/@optional

- (void)myProtocolMethod;

@end

协议中的方法声明的关键字:(主要是为了方便程序员之间的交流)

1.@required(默认):要求实现,如果没有实现,会有警告;

2.@optional:不要求实现,怎样都不会有警告。   

协议是多个类共享的一个方法列表,协议中列出的方法没有相应的实现。如果一个类采用MyProtocol协议,则必须实现名为myProtocolMethod 的方法

通过在@interface 行的一对尖括号<...>内列出协议名称,可以告知编译器你正在采用一个协议。这项协议的名称放在类名和它的父类名称之后,

如下所示:

@interface AddressBook: NSObject <myProtocol>

这说明, AddressBook 是父类为AddressBook 的对象,并且它遵守myProtocolMethod 协议在AddressBook 的实现部分,编译器期望找到定义的myProtocolMethod 方法。

如果采用多项协议,只需把它们都列在尖括号中,用逗号分开:

@interface AddressBook: NSObject < myProtocol , yourProtocol >

以上代码告知编译器AddressBook 类采用myProtocolMethod 和yourProtocolMethod 协议。这次,编译器将期望在AddressBook 的实现部分看到为这些协议列出的所有方法的实现。

有关协议的注意事项:

A、如果一个类遵守某项协议,那么它的子类也遵守该协议。

B、协议不引用任何类,它是无类的(classless)。任何类都可以遵守某项协议。

C、限制对象类型:

   通过在类型名称之后的尖括号中添加协议名称,可以借助编译器的帮助来检  

   查变量的一致性,如下:

   id <Drawing> currentObject;

   这告知编译器currentObject 将包含遵守Drawing 协议的对象。如果向 currentObject 指派静态类型的对象,这个对象不遵守Drawing 协议,编译器将给出warning。

   再次提到id 类型,如果向currentObject 指派一个id 变量,不会产生这条消息,因为编译器不知道存储在id 变量中的对象是否遵守Drawing 协议。

D、如果这个变量保存的对象遵守多项协议,则可以列出多项协议,如下:

   id <Drawing, Drawing 1> currentObject;

E、协议间的遵守:例如:

   @protocol Drawing3D <Drawing>

   说明Drawing3D 协议也采用了Drawing 协议。因此采用Drawing3D 协议的类都必须实现此协议列出的方法,以及Drawing 协议的方法。

   基协议:任何协议都要遵守基协议。

   基类遵守了基协议,所有类继承基类,也遵守基协议。

F、分类也可以采用一项协议,如:

@interface Fraction (stuff) <NSCopying, NSCoding>

此处,Fraction 拥有一个分类stuff,这个分类采用了NSCopying 和NSCoding 协议。

注:1.@property中声明的属性也可做一个遵守协议的限制:

      @property  (nonatomic,strong)类名<协议名>  *属性名;

    2. 协议可定义在单独的.h文件中,也可定义在类中:

      (1)如果这个协议只用在某个类中,应该把协议定义在类中;

      (2)如果这个协议用在很多个类中,应该把协议定义在单独.h文件中。

    另外:分类可定义在单独的.h文件中,也可以定义在原来类中,一般都定义在.h文件中,定义在原来文件中的分类,只要求看懂代码。

四、练习

代理模型设计:

Person.h:

#import <Foundation/Foundation.h>

#import "TiketDelegate.h"

@interface Person : NSobject <TiketDelegate>

- (void)BuyTiket;

@property(nonatomic,retain) id<TiketDelegate> delegate;

@end

Person.m:

#import "Person.h"

@implementation Person

- (void)BuyTiket

{

  double monkey = [_delegata tiketMonkey];

  int number = [_delegate tiketNumber];

  NSLog(@"找到一个代理,询问票价是:%f,剩余张数是:%d",monkey,number);

}

- (void)dealloc

{

   [_delegate release];

   [super dealloc];

}

@end 

TiketDelegante.h:

     #import <Foundation/Foundation.h>

    @protocol TiketDelegate <NSobject>

     @required

     - (double)tiketMonkey;

 

    - (int)tiketNumber;

@end

Agent.h:

     #import <Foundation/Foundation.h>

     #import "TiketDelegate.h"

     @implementation Agent : NSobject <TiketDelegate>

@end

Agent.m:

#import "Agent.h"

@implementation Agent

- (double)TiketMonkey

{

  return 100;

- (int)TiketNumber

{

  return 10;

}

@end

main.m:

#import <Foudation/Foundation.h>

#import "Person.h"

#impiort "Agent.h"

int main()

{

  @autoreleasepool{

   Person *p = [[[Person alloc] init] autorelease];

   Agent *a = [[[Agent alloc] init] autorelease];

 

   p.delegate = a;

   [p BuyTiket];

                 }



基于MMSkeleton工具包中的ST-GCN模型实现一种基于动态拓扑图的人体骨架动作识别算法python源码+使用说明.zip 改进ST-GCN模型的骨架拓扑图构建部分,使用持续学习思想动态构建人体骨架拓扑图. 将具有多关系特性的人体骨架序列数据重新编码为关系三元组, 并基于长短期记忆网络, 通过解耦合的方式学习特征嵌入. 当处理新骨架关系三元组时, 使用部分更新机制 动态构建人体骨架拓扑图, 将拓扑图送入ST-GCN进行动作识别。 运行MMSKeleton工具包参考[GETTING_STARTED.md](./doc/GETTING_STARTED.md) - 单独使用ST-GCN模型进行人体动作识别参考[START_RECOGNITION.md](./doc/START_RECOGNITION.md) - 训练基于动态拓扑图的人体骨架动作识别算法 ``` shell cd DTG-SHR python ./mmskeleton/fewrel/test_lifelong_model.py ``` - 测试基于动态拓扑图的人体骨架动作识别算法 ``` shell cd DTG-SHR python ./mmskeleton/fewrel/train_lifelong_model.py ``` - 可视化算法运行结果 基于web server搭建前端 [[参考]](https://blog.csdn.net/gzq0723/article/details/113488110) 1、前端模块:包含 'static与'templates'文件夹为界面展示相关的代码。 templates里面包含了两个html的结构文档,用来定义浏览器的显示界面。 static里面的css和img用来修饰界面。 2、服务模块: servel.py里面是web服务的一个业务逻辑。 运行算法性能可视化web服务 ``` shell cd DTG-SHR python ./server.py ``` 【备注】 1、该资源内项目代码百分百可运行,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值