【黑马程序员】---ARC、block类型和protocol协议总结

本文详细介绍了iOS开发中的ARC自动引用计数、Block闭包及Protocol协议的核心概念和使用技巧,包括ARC的工作原理、Block的基本用法及Protocol的定义与应用。
------- android培训java培训、期待与您交流! ----------


ARC、block类型和protocol协议总结


1.ARC

ARC是自iOS 5之后增加的新特性,完全消除了手动管理内存的烦琐,编译器会自动在适当的地方插入适当的retain、release、autorelease语句。

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


 指针分2种:


(1) 强指针:默认情况下,所有的指针都是强指针 __strong
 (2)弱指针:__weak

int main()
{
    Dog *d = [[Dog alloc] init];
    
    Person *p = [[Person alloc] init];
    p.dog = d;
    
    d = nil;
    
    NSLog(@"%@", p.dog);
    
    return 0;
}

    // 错误写法(没有意义的写法)
    __weak Person *p = [[Person alloc] init];

@implementation Dog
- (void)dealloc
{
    NSLog(@"Dog is dealloc");
}
@end

心得体会:

(1)不允许调用release、retain、retainCount

(2)允许重写dealloc,但是不允许调用[super dealloc]


@property的参数

(1)strong :成员变量是强指针(适用于OC对象类型)
(2)weak :成员变量是弱指针(适用于OC对象类型)
(3)assign : 适用于非OC对象类型

@class Dog;

@interface Person : NSObject

@property (nonatomic, strong) Dog *dog;


@property (nonatomic, strong) NSString *name;

@property (nonatomic, assign) int age;

@end
心得体会:引用ARC之后,以前的retain改为用strong,assign不变。

ARC循环引用解决方案:

 (1) ARC
 1端用strong,另1端用weak
 
(2)非ARC
 1端用retain,另1端用assign


2.Block

Block封装了一段代码,可以在任何时候执行。


定义block

	int (^sumBlock)(int, int);
 void (^myBlock)();

block封装代码

 ^(int a, int b) {
    return a - b;
 };
 
 ^() {
    NSLog(@"----------");
 };
 
 ^ {
    NSLog(@"----------");
 };
 block访问外面变量

block内部可以访问外面的变量
(1) 默认情况下,block内部不能修改外面的局部变量

(2)给局部变量加上__block关键字,这个局部变量就可以在block内部修改


利用typedef定义block类型

typedef int (^MyBlock)(int, int);
 // 以后就可以利用MyBlock这种类型来定义block变量
 MyBlock block;
 MyBlock b1, b2;
 
 b1 = ^(int a, int b) {
    return a - b;
 };
 
 MyBlock b3 = ^(int a, int b) {
    return a - b;
 };
利用typedef定义block类型和指向指针的函数的对比

typedef int (*SumP)(int, int);

typedef int (^MyBlock)(int, int);
心得体会:

(1)block的标记^,。

(2)目前所学的block比较简单,只是一些基本用法,多用几次就好了。


3.protocol协议

协议可以用来声明一大堆方法(不能声明成员变量)

(1)协议的定义

 @protocol 协议名称 <NSObject>
  // 方法声明列表....
 @end

(2)如何遵守协议

 @interface 类名 : 父类名 <协议名称1, 协议名称2>
 
 @end
 
 // 2> 协议遵守协议
 @protocol 协议名称 <其他协议名称1, 其他协议名称2>
 
 @end

(3)协议中方法声明的关键字

 1> @required (默认)
   要求实现,如果没有实现,会发出警告
 
 2> @optional
   不要求实现,怎样不会有警告

// 定义了一个名叫MyProtocol的协议
@protocol MyProtocol <NSObject>
// @required 要求实现,不实现就会发出警告
// @optional 不要求实现

- (void)test4;

@required
- (void)test;
- (void)test2;

@optional
- (void)test3;

@end
(4)定义一个变量的时候,限制这个变量保存的对象遵守某个协议

 // 类名<协议名称> *变量名;
 NSObject<MyProtocol> *obj;
 // id<协议名称> 变量名;
 id<MyProtocol> obj2;
// 要求obj3保存的对象必须是遵守是MyProtocol这个协议
    
    NSObject<MyProtocol> *obj3 = [[NSObject alloc] init];
(5)@property中声明的属性也可用做一个遵守协议的限制

// @property (nonatomic, strong) 类名<协议名称> *属性名;
 @property (nonatomic, strong) Dog<MyProtocol> *dog;
// @property (nonatomic, strong) id<协议名称> 属性名;
 @property (nonatomic, strong) id<MyProtocol> dog2;

(6)协议可用定义在单独.h文件中,也可用定义在某个类中

1> 如果这个协议只用在某个类中,应该把协议定义在该类中
 
 2> 如果这个协议用在很多类中,就应该定义在单独文件中


基协议

NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它


心得体会:

(1)其实分类可用定义在单独.h和.m文件中,也可用定义在原来类中。

(2)如果用@required关键字描述了方法,如果没有实现,会发出警告。

(3)建议每个新的协议都要遵守NSObject协议


4.协议的应用-代理模式

代理模式的设计原则,首先得拥有某个代理对象属性,其次要很清楚代理有哪些方法,最后要保证能解耦

#import <Foundation/Foundation.h>
#import "TicketDelegate.h"

@interface Person : NSObject

- (void) buyTicket;

// 拥有一个代理属性
// id代表代理的类名随便
// 但必须遵守TicketDelegate协议
@property (nonatomic, retain) id<TicketDelegate> delegate;

@end

心得体会:

(1)首先定义一个protocol,在其中定义一些和代理沟通的方法

(2)让类拥有一个代理属性,id<protocol>delegate,用于接收代理

(3)让类遵守协议,实现其中的方法,才能成为代理类。













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值