黑马程序员—06OC内存管理_01
来源:互联网 发布:三星s5网络模式仅限2g 编辑:程序博客网 时间:2024/06/05 02:44
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、description方法和SLE
1> description
包括类方法和对象方法两种 :
* -description(对象方法)
使用NSLog和@%输出某个对象时,会调用对象的description方法,并拿到返回值进行输出。
* +description(类方法)
使用NSLog和@%输出某个对象时,会调用类对象的description方法,并拿到返回值进行输出,把整个对象一次性打印出来,打印对象使用%@。
使用@%打印对象如(“@%”,P)默认打印输出为<类名:内存地址>,虽然字符串也是对象,但字符串在使用@%打印时情况特殊。
2> SLE
SLE : SLE其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址后就可以调用方法。这些都是运行时特性,发消息就是发送SEL,然后根据SEL找到地址,调用方法。
3>举例
Person类的声明 :
#import <Foundation/Foundation.h>@interface Person : NSObject@property int age;@property NSString *name;@end
Person类的实现 :
#import "Person.h"@implementation Person// 决定了实例对象的输出结果- (NSString *)description{ return [NSString stringWithFormat:@"age=%d, name=%@", _age, _name];}// 决定了类对象的输出结果+ (NSString *)description{ return @"Abc";}@end主函数 :
int main(){ // 输出行号 NSLog(@"%d", __LINE__); // 输出源文件的名称 printf("%s\n", __FILE__); Person *pp = [[Person alloc] init]; // 指针变量的地址 NSLog(@"%p", &pp); // 对象的地址 NSLog(@"%p", pp); // <类名:对象地址> NSLog(@"%@", pp); Class c = [Person class]; // 1.会调用类的+description方法 // 2.拿到+description方法的返回值(NSString *)显示到屏幕上 NSLog(@"%@", c); Person *p = [[Person alloc] init]; p.age = 20; p.name = @"Jack"; NSLog(@"%@", p); return 0;}
4> 总结
description 下面代码会发生死循环。
- (NSString *)description{NSLog(@"%@", self);return @"0000";}</span>
SLE寻找方法的过程:
Person *p=[[Person alloc] init];[p test];
* 首先把test这个方法名包装成sel类型的数据;
* 根据SEL数据找到对应的方法地址;
* 根据方法地址调用相应的方法。
* 注意:在这个操作过程中有缓存,第一次找的时候是一个一个的找,非常耗性能,之后再用到的时候就直接使用。
关于_cmd:每个方法的内部都有一个-cmd,代表着当前方法。
二、BOLCK
1> 简介
* BOLCK :苹果推荐的类型,效率高,在运行中保存代码。用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行。
* BOLCK和函数的相似性:可以保存代码;有返回值;有形参;调用方式一样。
* 标示符是^。
2> 基础使用
* 定义block变量 :
int (^sumBlock)(int, int); void (^myBlock)();
* 利用block封装代码(可以有参,亦可无参) :
^(int a, int b) { return a - b; }; ^() { NSLog(@"----------"); }; ^ { NSLog(@"----------"); };
* block访问外面变量 :
int main(){ int a = 10; __block int b = 20; void (^block)(); block = ^{ // block内部可以访问外面的变量 //NSLog(@"a = %d", a); // 默认情况下,block内部不能修改外面的局部变量 // a = 20; // 给局部变量加上__block关键字,这个局部变量就可以在block内部修改 b = 25; }; block(); return 0;}
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;};
3> 举例
#import <Foundation/Foundation.h>typedef int (*SumP)(int, int);typedef int (^MyBlock)(int, int);int sum(int a, int b){ return a + b;}int main(){ MyBlock sumBlock; sumBlock = ^(int a, int b) { return a + b; }; MyBlock minusBlock = ^(int a, int b) { return a - b; }; MyBlock multiplyBlock = ^(int a, int b) { return a * b; }; NSLog(@"%d - %d - %d", multiplyBlock(2, 4), sumBlock(10 , 9), minusBlock(10, 8)); return 0;}
4> 总结
三、protocol
1> 简介
* Protocol:就一个用途,用来声明一大堆的方法(不能声明成员变量),不能写实现。
* 只要某个类遵守了这个协议,就拥有了这个协议中的所有方法声明。
*只要父类遵守了某个协议,那么子类也遵守。
* Protocol声明的方法可以让任何类去实现,protocol就是协议。
* OC不能继承多个类(单继承)但是能够遵守多个协议。继承(:),遵守协议(< >)
* 基协议:<NSObject>是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。
*协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明。
2> 基本使用
* 创建协议 :
#import <Foundation/Foundation.h>// 定义了一个名叫MyProtocol的协议@protocol MyProtocol <NSObject>// @required 要求实现,不实现就会发出警告// @optional 不要求实现- (void)test4;@required- (void)test;- (void)test2;@optional- (void)test3;@end
* 遵守协议 :
#import <Foundation/Foundation.h>@class Hashiqi;@protocol MyProtocol2;@protocol MyProtocol3;// 只要一个类遵守了某一份协议,就能拥有这份协议中的所有方法声明// : 继承父类// <> 遵守协议@interface Person : NSObject <MyProtocol3, MyProtocol2>@property (nonatomic, strong) id<MyProtocol2> obj;@property (nonatomic, strong) Hashiqi *dog;@end
* 完成协议中方法的实现在类的实现(@implementation)中实现。
3> 总结
* 协议的定义 :
@protocol 协议名称 <NSObject>
// 方法声明列表....
@end
* 如何遵守协议 :
1> 类遵守协议
@interface 类名 : 父类名 <协议名称1, 协议名称2>
@end
2> 协议遵守协议
@protocol 协议名称 <其他协议名称1, 其他协议名称2>
@end
* 协议中方法声明的关键字
1> @required (默认)
要求实现,如果没有实现,会发出警告。
2> @optional
不要求实现,怎样不会有警告。
* 定义一个变量的时候,限制这个变量保存的对象遵守某个协议。
类名<协议名称> *变量名;
id<协议名称> 变量名;
NSObject<MyProtocol> *obj;
id<MyProtocol> obj2;
如果没有遵守对应的协议,编译器会警告。
* @property中声明的属性也可用做一个遵守协议的限制
@property (nonatomic, strong) 类名<协议名称> *属性名;
@property (nonatomic, strong) id<协议名称> 属性名;
@property (nonatomic, strong)Dog<MyProtocol> *dog;
@property (nonatomic, strong)id<MyProtocol> dog2;
* 协议可用定义在单独.h文件中,也可用定义在某个类中。
1> 如果这个协议只用在某个类中,应该把协议定义在该类中。
2> 如果这个协议用在很多类中,就应该定义在单独文件中。
* 分类可用定义在单独.h和.m文件中,也可用定义在原来类中
1> 一般情况下,都是定义在单独文件。
2> 定义在原来类中的分类,只要求能看懂语法。
- 黑马程序员—06OC内存管理_01
- 黑马程序员---【OC语言】06内存管理
- 黑马程序员——OC---内存管理
- 黑马程序员——OC内存管理
- 黑马程序员——OC内存管理
- 黑马程序员——【OC】内存管理
- 黑马程序员——OC内存管理
- 黑马程序员——OC内存管理
- 黑马程序员——OC内存管理
- 黑马程序员——OC内存管理
- 黑马程序员——[OC]内存管理
- 黑马程序员 — OC(内存管理)
- 黑马程序员—OC内存管理
- 黑马程序员-OC-内存管理
- 黑马程序员--oc:内存管理
- [黑马程序员][OC]内存管理
- 黑马程序员-OC内存管理
- 黑马程序员---OC--内存管理
- Android中集成第三方库的方法和问题
- 数据库操作(使用FMDB)
- 杂七杂八 android小工具类
- From feature descriptors to deep learning: 20 years of computer vision
- 每天进步一点
- 黑马程序员—06OC内存管理_01
- hadoop学习之hadoop完全分布式集群安装
- POJ 3252 Round Numbers (数位DP)
- 检测远程端口是否打开
- 黑马程序员—07OC内存管理_02
- tower of hanoi(汉诺塔)问题 按步骤分析--取自《严蔚敏·数据结构》 P55
- 黑马程序员—08Foundation框架_结构体
- ContentPane
- 数学之路-python计算-Theano(1)