OC加强-day03
#program mark - 0_18 分类的使用注意 [掌握]
1.分类的作用
作用:讲一个类分为多个模块,将相似功能的方法写在同一个模块中,方便我们后面代码的维护
"强调
1.分类中只能写方法的声明和实现,你不要直接去写属性,写了立即报错
2.在分类的.h中用@property声明的属性,不会生成属性,只会在分类的.h里面生成"所谓的"属性的set/get的声明.
3.在分类中到底如何访问本类的属性.
1>分类中是不能直接访问本类中的真私有属性,但是可以通过set/get方法访问
2>分类中可以直接访问本类.h中@interface中直接声明的属性
#program mark - 0_19 非正式协议 [现在先听懂,等学了Foundation框架再回来复习]
为系统自带的类写分类,就叫做非正式协议
#program mark - 02 延展的基本使用 [掌握]
"强调
1.类延展也是类的一种分类,这个分类和本类公用一个.m,所以它是一个只有.h的文件
2.类延展没有没有名字
"练习
给一个类YYNetworkTool,添加一个类延展download
3.和普通分类的区别
1>普通分类直接创建属性,会立即报错,类延展却可以创建属性
2>普通分类用@property生成的属性,不会生成属性,只会在分类的.h里面生成"所谓的"属性的set/get的声明,但是延展,会在主类的.m中生成私有属性和set/get的实现.以及当前类延展的.h中生成属性的set/get方法的声明.
"注意:由于延展和主类公用一个.m,又由于编译只编译.m文件.所以要在主类中导入类延展的.h,否则延展中的代码没有效果
#program mark - 03 延展的使用场景 [掌握]
1.什么叫私有的@property
生成的属性的set/get的声明也在.m里面
2.类延展到底有什么用?
就是用来声明不想在类外部使用的属性和方法.当方法或者属性仅限于当前类内部使用的时候
#program mark - 04 block变量的声明 [掌握]
1.变量是什么?
变量就是内存中若干个字节,用来存储数据.
int 型变量 里面存储 整型数据
"函数的指针"类型 里面存储 一个函数的地址
block类型的变量 里面存储 一段代码
2.变量的声明
1>int
数据类型 变量名;
int num_int;
2>函数的指针
//函数的指针指向一个返回值为void,参数是两个double型的函数
void (*p)(double num1,double num2);
//函数的指针指向一个返回值为void,没有参数的函数
void (*p1)();
3>block
//定义一个block的变量存储一个返回值为void,参数是两个double型代码块
void (^xiaoyueBlock)(double num1,double num2);
//定义一个block的变量存储一个返回值为void,没有参数的代码块
void (^xiaoyue2)();
#program mark - 知识点复习
1.分类
1>是什么
当一个类中有很多属于不同范畴的方法的时候,通常使用分类来把这些方法进行分类,有一个类叫本类,其他的叫分类.
2>有什么特点?
1)和主类在一起共同构成了一个类
2)不能声明属性,只能添加方法
3)可以实现和主类同名的方法,编译的时候会覆盖主类的方法.如果调用此方法,调用分类的.
4)如果两个分类实现的方法名字相同,谁最后编译调用谁的.
5)主类肯定比分类先编译.
2.延展
1>什么是延展
延展也是一个分类,只不过这个分类和主类公用一个.m文件.并且延展是没有名字的
2)有什么特点
1)可以声明属性,也可以声明方法
2)一般是把类的延展写在主类的.m里,延展中声明的方法/属性,只能在当前类的内部使用,在当前类的外部无法访问
"例子
一个ViewController代表一个界面,内部的显示/内存管理由当前控制器类自己管理,外界不需要知道内部做了什么,此时控制器对象的一些属性方法,就可以写在控制器.m中的延展里
3.非正式协议
1>是什么?
就是给苹果提供的类写分类
"例子
NSString 添加分类 --->统计一个字符串对象内部阿拉伯数字个数
.h
@interface NSString (YYfenlei)
-(int)numOfAlaboSuzi;
@end
.m
-(int)numOfAlaboSuzi
{
// self 就代表当前字符串对象
}
4.block变量的定义
//1.无参数无返回值block变量 xiaoyueblock
void (^xiaoyueBlock)();
//2.有一个int型参数返回值bint型的lock变量 xiaoyue2
int (^xiaoyue2)(int opNum);
//3.定义一个有三个参数,int,double,char,返回值是double类型的block 变量xiaoyue3
double (^xiaoyue3)(int opNum1,char opNum2,double opNum3);
"变量的赋值
1>int
int num;
num = 10;
2>函数的指针
int add(int a,int b);
int add(int a,int b)
{
return a+b;
}
//只是定义了一个函数的指针,还没有和任何函数关联
int (*p)(int a,int b);
//使用函数名给函数的指针赋值
p=add;
3>
//1.无参数无返回值block变量 xiaoyueblock
void (^xiaoyueBlock)();
xiaoyueBlock = ^void (){
代码;
};
//2.有一个int型参数返回值bint型的lock变量 xiaoyue2
int (^xiaoyue2)(int opNum);
xiaoyue2 = ^int (int opNum){
return opNum + 10;
};
//3.定义一个有三个参数,int,double,char,返回值是double类型的block 变量xiaoyue3
double (^xiaoyue3)(int opNum1,char opNum2,double opNum3);
xiaoyue3 = ^double(int opNum1,char opNum2,double opNum3){
return 1.1 + opNum2;
};
int main()
{
double dou = xiaoyue3(2,'a',1.1);
return 0;
}
#program mark - 05 block变量的初始化和使用 [掌握]
此知识点的复习见OC加强03视频笔记/05 block变量的初始化和使用.pdf
#program mark - 06 block的简写 [听懂]
此知识点的复习见OC加强03视频笔记/06 block的简写.pdf
"强调
自己写的时候不要简写,能看懂别人的简写
"例子
//定义一个有三个参数,int,double,char,返回值是double类型的block 变量xiaoyue3
//完整写法
double (^xiaoyue3)(int opNum1,char opNum2,double opNum3)= ^double(int opNum1,char opNum2,double opNum3){
return 1.1 + opNum2;
};
//简化写法
double (^xiaoyue3)(int ,char,double )= ^(int opNum1,char opNum2,double opNum3){
return 1.1 + opNum2;
};
#program mark - 07 使用typedef简化block定义
此知识点的复习见OC加强03视频笔记/07 使用typedef简化block定义.pdf
"复习
//定义一个 Lint别名 代表long int 这种类型
typedef long int Lint;
//定义一个 arr别名 代表 长度是3的整型数组 这种类型
typedef int arr[3];
//定义一个 xiaoyue别名 代表 返回值是int,参数是空的block 这种类型
typedef int (^xiaoyue)();
int main()
{
Lint num = 1000;
//定义一个长度是3的int型数组brr
arr brr = {1,2,3};
//定义一个返回值是int没有参数的变量
xiaoyue xiaoxiaoyue;
return 0;
}
"练习
利用typedef定义一个别名叫做hello的无参无返回值的block类型,定义一个hello类型block变量并调用
利用typedef定义一个别名叫做add的有两个int参数参无返回值的block类型,定义一个add类型block变量并调用
typedef void (^hello)();
typedef void (^add)(int opNum1,int opNum2);
int main()
{
hello xiaoyueblock1;
xiaoyueblock = ^void(){
NSLog(@"hello world!");
};
add xiaoyueblock2 = ^void(int opNum1,int opNum2){
NSLog(@"和是%d",opNum2+opNum1);
};
return 0;
}
#program mark - 08 block访问外部变量的问题 [掌握]
1.block类型的变量,可以定义变量的,
int main()
{
//无返回值有一个int参数block变量
void (^xiaoyuedashiBlock)(int opNum) = ^void(int num1){
int num2 = 10;
num2++;
num1++;
NSLog(@"%d-----%d",num1,num2);
};
xiaoyuedashiBlock(22);
return 0;
}
2.block里面存代码内部是可以访问外部变量的.
//定义一个全局变量
int quanju_num = 10;
int main()
{
//无返回值有一个无参数block变量
void (^xiaoyuedashiBlock)();
//定局部变量
int jubu_num = 20;
xiaoyuedashiBlock = ^void(){
NSLog(@"%d---%d",quanju_num,jubu_num);
};
xiaoyuedashiBlock();
return 0;
}
3.block内的代码可以修改全局变量,但是不能修改外部变量
//定义一个全局变量
int quanju_num = 10;
int main()
{
//无返回值有一个无参数block变量
void (^xiaoyuedashiBlock)();
//定局部变量
int jubu_num = 20;
xiaoyuedashiBlock = ^void(){
// quanju_num++;没问题
// jubu_num++;编译报错
NSLog(@"%d---%d",quanju_num,jubu_num);
};
xiaoyuedashiBlock();
return 0;
}
4.block内的代码如果一定要"修改"外部变量,可以在定义这个变量的时候添加__block修饰这个变量
//定义一个全局变量
int quanju_num = 10;
int main()
{
//无返回值有一个无参数block变量
void (^xiaoyuedashiBlock)();
//定局部变量
__block int jubu_num = 20;
xiaoyuedashiBlock = ^void(){
quanju_num++;
jubu_num++;
NSLog(@"%d---%d",quanju_num,jubu_num);
};
xiaoyuedashiBlock();
return 0;
}
5.为什么block内的代码可以修改全局变量,但是不能修改外部变量??
因为block
//定义一个全局变量
int quanju_num = 10;
int main()
{
//无返回值有一个无参数block变量
void (^xiaoyuedashiBlock)();
{
//定局部变量
__block int jubu_num = 20;
xiaoyuedashiBlock = ^void(){
quanju_num++;
jubu_num++;
NSLog(@"%d---%d",quanju_num,jubu_num);
};
}
xiaoyuedashiBlock();
return 0;
}
#program mark - 09 block作为函数的参数
//定义一个函数无返回值参数是一个int型数据
void test1(int a)
{
a++;
printf("%d\n",a+10);
}
//定义一个参数是block的函数
void test( void (^xiaoyuedashiBlock)())
{
xiaoyuedashiBlock();
}
int main()
{
//把一个没有返回值的没有参数的block当做上面函数的参数
void (^youse)() = ^void(){
NSLog(@"block执行了!");
};
test);
}
"练习
模拟IOS开发:
写一个无返回值的函数,函数名requestData
函数内有三个顺序执行的功能,发送网络请求,解析请求到的数据,展示数据,这三个功能用NSLog模拟.
函数要求有一个block参数,这个block里面的代码用来播放动画,这段代码必须在函数内解析数据后调用(播放动画也用NSLog模拟).
1.先写自己能做
1>定义函数
1)发送请求 NSLog
2)解析数据 NSLog
3)展示数据 NSLog
void requestData();
void requestData()
{
NSLog(@"发送请求");
NSLog(@"解析数据");
NSLog(@"展示数据");
}
2.实现函数参数的定义
void requestData(void (^dongHuang)());
void requestData(void (^dongHuang)());
{
NSLog(@"发送请求");
NSLog(@"解析数据");
dongHuang();
NSLog(@"展示数据");
}
3.实现调用
int main()
{
void (^donghuablock)() = ^void(){
NSLog(@"播放一个翻转动画");
};
requestData(donghuablock);
return 0;
}
"新需求
实现网络解析了多长时间就播放多久的动画
void requestData(void (^dongHuang)(double sec));
void requestData(void (^dongHuang)(double sec))
{
NSLog(@"发送请求");
NSLog(@"解析数据");//5s
dongHuang(9.0);
NSLog(@"展示数据");
}
int main()
{
void (^donghuablock)(double sec);
donghuablock = ^void(double sec){
NSLog(@"播放一个旋转动画播放%lf秒",sec);
};
requestData(donghuablock);
return 0;
}
#program mark -10 block作为方法的参数 [掌握]
此知识点的复习见OC加强03视频笔记/10 block作为方法的参数.pdf
"强调
block作为参数的理解的要点
block是一种数据类型,block这种数据类型的变量,里面存储的就是代码.
block变量中存储的是代码,这个block变量可以传来传去,只要拿到这个block变量,就能调用变量里面存放的代码.
#program mark -11 block作为方法的参数2 [掌握]
"复习
1.定义字符串的两种方式
1>数组方式
char str[] = {'a','b','\0'};
2>指针方式
char *str2 = "ab";
2.什么是指针数组
是数组,只不过这个数组中存放的是指针.
3.指针字符串数组
是数组,里面存的是用指针方式定义的字符串
char *str1 = "手机响了";
char *str2 = "她喜欢我";
char *str3 = "我能反杀";
char *arr[3] = {
str1,
str2,
str3,
};
4.strcmp(字符串1,字符串2)函数数的使用步骤和原理
1>引入<string.h>
2>从两个字符串的第一个字符开始比较,比较对应的ASCII码,一旦有结果了就停止
字符串1==字符串2时候结果0
字符串1>字符串2时候结果>0
字符串1<字符串2时候结果<0
#include<string.h>
int main()
{
char *str1 = "ab";
char *str2 = "cA";
int result = strcmp(str1,str2);
printf("%d\n",result);
}
"需求
有一个指针字符串数组
char *countries[] =
{
"Nepal",
"Cambodia",
"Afghanistan",
"China",
"Singapore",
"Bangladesh",
"India",
"Maldives",
"South Korea",
"Bhutan",
"Japan",
"Sikkim",
"Sri Lanka",
"Burma",
"North Korea",
"Laos",
"Malaysia",
"Indonesia",
"Turkey",
"Mongolia",
"Pakistan",
"Philippines",
"Vietnam",
"Palestine"
};
1.定义函数把字符串按照大小排序
void paiXuWithASCII(char * countries[],int length)
{
char *temp = nil;
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - i -1; j++) {
if(strcmp(countries[j],countries[j+1])>0)
{
temp = countries[j];
countries[j] = countries[j+1];
countries[j+1] = temp;
}
}
}
for (int i = 0; i < length; i++) {
printf("%s\n",countries[i]);
}
}
int main()
{
paiXuWithASCII(countries,24);
return 0;
}
2.定义一个函数,按照每个字符串长度排序
void paiXuWithASCII(char * countries[],int length)
{
char *temp = nil;
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - i -1; j++) {
if((int)strlen(countries[j])-(int)strlen(countries[j+1])<0)//用strlen表
{
temp = countries[j];
countries[j] = countries[j+1];
countries[j+1] = temp;
}
}
}
for (int i = 0; i < length; i++) {
printf("%s\n",countries[i]);
}
}
int main()
{
paiXuWithASCII(countries,24);
return 0;
}
3.调用这个函数实现排序,按照调用者的要求排序
//分析:比较上面两种实现,两种功能之间唯一不同的代码,在排序循环中的if语句的判断条件部分,能否把if判断语句,传到函数中,实现根据不同的需求进行潘旭
//1.确定的是传入的肯定是if判断条件中,和下面两句代码类似的
if(strcmp(countries[j],countries[j+1])>0)
if(strlen(countries[j])-strlen(countries[j+1])<0)//用strlen表
//2分析传入的代码
//1>需要返回值吗--->需要 0/1
//2>需要参数吗? -->肯定要参数,countries[j],countries[j+1]
BOOL (^xiaoyuedashiBlock)(char * opXing1,char * opXing2) = ^BOOL(char * opXing1,char * opXing2){
BOOL result = ((int)strlen(opXing1)-(int)strlen(opXing2)<0)
return result;
};
4.修改函数
void paiXuWithUsrBlock(char * countries[],int length,BOOL (^xiaoyuedashiBlock)(char * opXing1,char * opXing2))
{
char *temp = nil;
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - i -1; j++) {
if( xiaoyuedashiBlock(countries[j],countries[j+1]))
{
temp = countries[j];
countries[j] = countries[j+1];
countries[j+1] = temp;
}
}
}
for (int i = 0; i < length; i++) {
printf("%s\n",countries[i]);
}
}
int main()
{
BOOL (^xiaoyuedashiBlock)(char * opXing1,char * opXing2) = ^BOOL(char * opXing1,char * opXing2){
BOOL result = ((int)strlen(opXing1)-(int)strlen(opXing2)<0);
BOOL result2 = (strcmp(opXing1, opXing2)>0);
return result;
};
paiXuWithUsrBlock(countries,24,xiaoyuedashiBlock);
return 0;
}
#pragma mark 12 block与函数的异同 [掌握]
1.相同点
都是可以存储一段能够实现特定功能的代码
2.不同
1>block是一种数据类型,函数不是数据类型,函数就是一段代码
2>block可以直接做参数传递,函数是不可以的.函数的指针当参数传递本质是间接传递"了解一下
void test()
{
printf("xxx\n");
}
void (*p)() = test;
void useTest(void (*p)())
{
p();
}
int main()
{
useTest(p);
return 0;
}
3.block是可以做函数的返回值的.
1>定义一个无返回值,有一个int型参数的block变量
void (^xiaoyuedashiBlock)(int num) = ^void(int num){
NSLog(@"%d",num);
};
2>定义无返回值无参数的函数
void test()
{
}
3>希望上面函数返回一个block
typedef void (^xiaoyuedashiBlock)(int num);
xiaoyuedashiBlock test()
{
void (^xiaoyuedashiBlock)(int num) = ^void(int num){
NSLog(@"%d",num);
};
return xiaoyuedashiBlock;
}
//测试
int main()
{
xiaoyuedashiBlock b1 = test();
b1(2);
return 0;
}
注意:
1.一般我们不这样写.这样可阅读性太差.
2.当函数的返回值是block类型的时候,返回值类型必须要用typedef的形式给出,否则报错
//下面代码会报错
typedef void (^)(int num) test()
{
void (^xiaoyuedashiBlock)(int num) = ^void(int num){
NSLog(@"%d",num);
};
return xiaoyuedashiBlock;
}
#pragma mark 13 协议的基本使用 [掌握]
协议:@protocol
协议:专门用来写方法声明的,协议中不能写属性
遵守协议的类,这个类就拥有了这份协议中的所有方法的声明,而不用自己去定义
OC加强-day03的更多相关文章
- OC基础-day03
1#pragma mark - Day03_01_对象作为方法的返回值 1) 对象是可以作为方法的返回值的,返回值应该写这个类指针类型. - (MkDog *)buyDog; 代表方法执行完毕之后,有 ...
- iOS代码规范(OC和Swift)
下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...
- 用C语言封装OC对象(耐心阅读,非常重要)
用C语言封装OC对象(耐心阅读,非常重要) 本文的主要内容来自这里 前言 做iOS开发的朋友,对OC肯定非常了解,那么大家有没有想过OC中NSInteger,NSObject,NSString这些对象 ...
- 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比
C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...
- 嵌入式&iOS:回调函数(C)与block(OC)回调对比
学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...
- WebViewJavascriptBridge源码探究--看OC和JS交互过程
今天把实现OC代码和JS代码交互的第三方库WebViewJavascriptBridge源码看了下,oc调用js方法我们是知道的,系统提供了stringByEvaluatingJavaScriptFr ...
- OC泛型
OC泛型 泛型是程序设计语言的一种特性,他主要是为了限制类型的,比如OC中的数组,你可以限制他里面装的是NSString类型,泛型的话JAVA和C++都有的,大家要是对泛型不了解的话可以去百度一下. ...
- iOS学习15之OC集合
1.数组类 1> 回顾C语言数组 数组是一个有序的集合, 来存储相同数据类型的元素. 通过下标访问数组中的元素,下标从 0 开始. 2> 数组 数组是一个有序的集合,OC中的数组只能存储对 ...
- JS 与OC 交互篇
完美记录交互 CSDN博客: (OC调用JS) http://blog.csdn.net/lwjok2007/article/details/47058101 (JS调用OC) http://blog ...
随机推荐
- opencv源代码
源代码都在modules文件夹下.搜索一个函数比如dft,在win7下 找到了
- 分享form表单提交问题
前段时间做了一个form表单传值问题 当时觉得form表单的submit不就是提交form表单name的value值吗 ? 其实是对的 但是我做的是一个打印页面 需要把当前页面的元素传入下一个u ...
- 关于VNC黑屏的问题
注意: 1.vncserver启动后生成的ID号(1,2,3)要和VNCview里面填入的 ip:ID要保持一致 不然看到的就是黑屏 比如:vncserver启动后 产生: localhost.lo ...
- Java 下 SSL 通信原理及实例
有关SSL的原理和介绍在网上已经有不少,对于Java下使用keytool生成证书,配置SSL通信的教程也非常多.但如果我们不能够亲自动手做一个SSL Sever和SSL Client,可能就永远也不能 ...
- maven依赖规则
1.就近原则,传递依赖 A-B-C -> A-C 2.先声明原则 A-B-C D-E-C 依赖的规则阻止了jar包冲突
- 用普通PC主板的蜂鸣器给树莓派(RPI)加个报警器
这两天有点时间,捣鼓了下那闲置好久的树莓派,把普通PC主板的蜂鸣器作为树莓派的报警器用. Raspberry Pi有许多的GPIO(General Purpose Input Output:通用输入/ ...
- salt-minion安装脚本
#!/bin/bash cd /usr/local/src/ wget http://mirrors.sohu.com/fedora-epel/6/x86_64/epel-release-6-8.no ...
- heritrix 相关
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- DNF即将代替Yum
也许你会惊奇在新安装的 Fedroa 22中没有找到 yum 包,也不明白为何在调用 /usr/bin/yum 或使用各种 Yum 插件时会得到警告.嗯,你看到的没错,Yum 已经去了~.直白的说, ...
- G++ 教程(转)
简介 gcc and g++分别是GNU的c & c++编译器 gcc/g++在执行编译工作的时候,总共需要4步 1.预处理,生成.i的文件[预处理器cpp] 2.将预处理后的文 ...