objective-c 语法快速过(8)
Block(oc 的数据类型,很常用,本质是c结构体)
类似内联函数,从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。编译时,类似宏替换,使用函数体替换调用处的函数名
Block封装了一段代码,可以在任何时候执行
Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。
苹果官方建议尽量多用block。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多
Blocks的定义:
int (^MySum)(int, int) = ^(int a, int b) {
return a+b;
};
定义了一个叫MySum的blocks对象,它带有两个int参数,返回int。等式右边就是blocks的具体实现,Block可以访问局部变量,但是不能修改。
Block 类似一个语句,比如10;
int sum = ;
int (^MyBlock)(int) = ^(int num) {
sum++;//编译报错
return num * sum;
};
如果要修改就要加关键字:__block
__block int sum = 10;
能访问全局变量且也能修改全局变量
Blocks和函数指针对比(类似)
定义函数指针
int (*myFn)();
定义Blocks
int (^MyBlocks)(int,int);
调用函数指针
(*myFn)(10, 20);
调用Blocks
MyBlocks(10, 20);
Blocks的赋值
在声明的同时定义变量,然后赋值
int (^MySum)(int,int) = ^(int a,int b) {
return a + b;
};
也可先用typedef先声明类型,再定义变量进行赋值
typedef int (^MySum)(int,int);
MySum sum = ^(int a,int b) {
return a + b;
};
block要掌握的东西
1> 如何定义block变量(两种)
int (^sumBlock)(int, int);
void (^myBlock)();
2> 如何利用block封装代码
^(int a, int b) {
return a - b;
};
^() {
NSLog(@"----------");
};
3> block访问外面变量
* block内部可以访问外面的变量
* 默认情况下,block内部不能修改外面的局部变量
* 给局部变量加上__block关键字,这个局部变量就可以在block内部修改
4> 利用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;
};
protocol简单使用(很常见)
基本用途
用来声明一大堆方法(不能声明成员变量),仅仅是声明!
只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明
只要父类遵守了某个协议,就相当于子类也遵守了
协议的编写
@protocol 协议名称 // 方法声明列表 @end
某个类遵守协议
@interface 类名 : 父类 <协议名称> @end
协议中有2个关键字可以控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流
- @required:这个方法必须要实现(若不实现,编译器会发出警告)
- @optional:这个方法不一定要实现
协议遵守协议
- 一个协议可以遵守其他多个协议,多个协议之间用逗号 , 隔开
- 一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明
@protocol 协议名称 <协议1, 协议2> @end
基协议
- NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它
- 其实还有一个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
- NSObject协议中声明很多最基本的方法,比如description、retain、release等
- 建议每个新的协议都要遵守NSObject协议
定义变量时指定协议
// NSObject类型的对象,并且要遵守NSCopying协议 NSObject<NSCopying> *obj; // 任何OC对象,并且要遵守NSCoding协议 id<NSCoding> obj2;
在 xcode6里新建协议的方法:oc file 里如下类似窗口(包括新建分类也是如此)

建立.h 文件,因为协议就是用来声明方法的。头文件里声明即可。
// MyProtocol.h
#import <Foundation/Foundation.h>
// 定义了一个名叫MyProtocol的协议
@protocol MyProtocol <NSObject>
// @required 要求实现,不实现就会发出警告
// @optional 不要求实现
- (void)test4;
@required
- (void)test;
- (void)test2;
@optional
- (void)test3;
@end // MyProtocol2.h
#import <Foundation/Foundation.h>
@protocol MyProtocol2 <NSObject>
- (void)haha2;
@optional
- (void)haha3;
@end // MyPrototol3.h
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
// 一个协议遵守了另外一个协议,就可以拥有另一个协议的所有方法声明
@protocol MyProtocol3 <MyProtocol>
- (void)hehe;
@end /*文件名:Person.h */
#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 /*文件名:Person.m*/
#import "Person.h"
#import "MyProtocol2.h"
#import "MyProtocol3.h" @implementation Person
- (void)test
{}
@end // MyProtocol4.h
#import <Foundation/Foundation.h>
@protocol MyProtocol4 <NSObject>
@end /*文件名:Dog.h */
#import <Foundation/Foundation.h> @protocol MyProtocol2;
@interface Dog : NSObject <MyProtocol2>
@end /*文件名:Dog.m*/
#import "Dog.h"
#import "MyProtocol2.h" @implementation Dog
- (void)haha2
{
}
@end /*文件名:Hashiqi.h */
#import "Dog.h" @protocol MyDogProtocol <NSObject>
- (void)dogTest;
@end @interface Hashiqi : Dog<MyDogProtocol>
- (void)addTest;
@end @interface Hashiqi (Add)
- (void)addTest;
@end /*文件名:Hashiqi.m */
#import "Hashiqi.h" @implementation Hashiqi - (void)dogTest
{ } @end @implementation Hashiqi (Add)
- (void)addTest
{ }
@end // Hashiqi+MJ.h
#import "Hashiqi.h" @interface Hashiqi (MJ)
@end // Hashiqi+MJ.m
#import "Hashiqi+MJ.h"
@implementation Hashiqi (MJ)
@end // main.m
#import <Foundation/Foundation.h>
#import "MyProtocol.h"
#import "MyProtocol3.h"
#import "Person.h"
#import "Dog.h"
#import "Hashiqi.h" int main()
{
Person *p = [[Person alloc] init];
p.obj = [[Hashiqi alloc] init]; return ;
} void test()
{
//NSObject *obj = [[NSObject alloc] init]; //NSObject *obj2 = @"4324324"; // 要求obj3保存的对象必须是遵守是MyProtocol这个协议 //NSObject<MyProtocol> *obj3 = [[NSObject alloc] init]; NSObject<MyProtocol> *obj3 = [[Person alloc] init]; obj3 = nil; //id 相当于 NSObject *
id<MyProtocol> obj4 = [[Person alloc] init]; obj4 = nil; // 要求obj5,保存的对象必须遵守MyProtocol3、并且继承了Person
Person<MyProtocol3> *obj5 = [[Person alloc] init]; obj5 = nil;
}
协议的定义
@protocol 协议名称 <NSObject>
// 方法声明列表....
@end
如何遵守协议
1> 类遵守协议
@interface 类名 : 父类名 <协议名称1, 协议名称2>
@end
2> 协议遵守协议
@protocol 协议名称 <其他协议名称1, 其他协议名称2>
@end
3.协议中方法声明的关键字
1> @required (默认)
要求实现,如果没有实现,会发出警告
2> @optional
不要求实现,不会有警告
4.定义一个变量的时候,限制这个变量保存的对象遵守某个协议
类名<协议名称> *变量名;
id<协议名称> 变量名;
NSObject<MyProtocol> *obj;
id<MyProtocol> obj2;
如果没有遵守对应的协议,编译器会警告
5.@property中声明的属性也可用做一个遵守协议的限制
@property (nonatomic, strong) 类名<协议名称> *属性名;
@property (nonatomic, strong) id<协议名称> 属性名;
@property (nonatomic, strong) Dog<MyProtocol> *dog;
@property (nonatomic, strong) id<MyProtocol> dog2;
6.协议可用定义在单独.h文件中,也可用定义在某个类中
1> 如果这个协议只用在某个类中,应该把协议定义在该类中
2> 如果这个协议用在很多类中,就应该定义在单独文件中
7.分类可用定义在单独.h和.m文件中,也可用定义在原来类中
1> 一般情况下,都是定义在单独文件
2> 定义在原来类中的分类,只要求能看懂语法
欢迎关注
dashuai的博客是终身学习践行者,大厂程序员,且专注于工作经验、学习笔记的分享和日常吐槽,包括但不限于互联网行业,附带分享一些PDF电子书,资料,帮忙内推,欢迎拍砖!

objective-c 语法快速过(8)的更多相关文章
- Objective-C基础语法快速入门
Objective-C基础语法快速入门 2010-11-04 16:32 折酷吧 zheku8 字号:T | T 假如我们对面向对象的思维已经C语言都很熟悉的话,对于我们学习Objective-C将会 ...
- jenkins2 pipeline 语法快速参考
jenkins2 pipeline中常用的语法快速参考. 文章来自:http://www.ciandcd.com文中的代码来自可以从github下载: https://github.com/ciand ...
- Razor 语法快速参考
Razor 语法快速参考 本文引自:http://haacked.com/archive/2011/01/06/razor-syntax-quick-reference.aspx 语法名称 Raz ...
- 第二章 C#语法快速热身
C#语法快速热身 语法 if(条件表达式){ 代码块 } 语法 if(条件表达式){ 代码块 }else{ 代码块2 } 语法 if(条件表达式1){ 代码块1 if(条件表达式1)){ }else{ ...
- Less 语法快速入门
Less 语法快速入门 Less 是一门 CSS 预处理语言其可以运行在 Node 或浏览器端. 它将传统的 css 样式结构单一的排版顺序进行了优化,让我们可以通过层级嵌套的方式将 css 类名与H ...
- objective-c 语法快速过(6)内存管理原理
内存管理基本原理(最重要) 移动设备的内存极其有限(iphone 4内存512M),每个app所能占用的内存是有限制的(几十兆而已). 当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不 ...
- objective-c 语法快速过(4)
oc 里的字符串 字符串的快速创建(最简单的方法) NSStirng *str = @“Hello”;//oc的字符串都是@“”形式的 oc的字符串也是类的对象,是NSString类的对象,创建没有那 ...
- objective-c 语法快速过(1)
有一定 c++或者 java 基础,过一遍 oc 语法即可,都是相通的,个人认为难点是 oc 的内存管理,虽然有了 ARC,但是也需要学习下,因为有旧软件的维护. 建立在C语言的基础上,增加了一层小范 ...
- Emmet语法 —— 快速生成HTML结构
快速生成HTML结构语法 1.生成单个标签 : 标签名+tab,比如 div 然后tab 键, 就可以生成 <div></div> 2.生成多个相同标签 div*3 + tab ...
随机推荐
- mysql不能插入中文
mysql不能插入中文 解决办法: 1.打开终端,连接数据库 mysql -u root -p; 2.输入 satus; 查看状态 3.输入 set char set 'gbk'; 4.如果是已有的 ...
- 下载apk文件浏览器会直接打开并显示乱码的问题
今天同事反映他的apk文件在自己的老项目中下载有问题:下载apk文件浏览器会直接打开并显示乱码,在别的项目中就没有问题. 后分析response的content-type发现,老项目的类型是text/ ...
- jquery 购物车飞入效果
github https://github.com/amibug/fly demo https://github.com/amibug/fly
- springmvc入门的第一个小例子
今天我们探讨一下springmvc,由于是初学,所以简单的了解一下 springmvc的流程,后续会持续更新... 由一个小例子来简单的了解一下 springmvc springmvc是spring框 ...
- HTML Help WorkShop 创作、调用方法和技巧
一.在CHM 文件中所用到的弹出式菜单: 二.在HTML Help WorkShop 中不用显示的样式 (1).从右到右阅读顺序. (2).对话框 (3).滚动条在左边 (4).仅展开单个标题 ...
- 开始研究unreal4了
最后一个周末了,昨天去做了许多事,算是对最近的一些整理和了结吧.早上广州下雨了,9点起来吃了早餐之后又睡了1个小时.中午吃了泡面,幸福感max.晚上煎了菜脯蛋和肉卷,拖着拉着把<旋风十一人> ...
- 关于EF6的记录Sql语句 与 EntityFramework.Extend 的诟病
1.关于EF6的记录Sql语句,一个老生长谈的问题. 他生成的sql语句实在是烂,大家都这样说 2.EF6 更新删除不方便,没有批量操作.所以,有人出了EF6.Extend 大家用起来也很爽 基于以 ...
- 可在广域网部署运行的QQ高仿版 -- GGTalk总览
(最新版本:V5.5,2016.12.06 增加对MySQL数据库的支持.) (android移动端:2015.09.24 最初发布 ,2016.11.25 最后更新) GGTalk(简称GG)是 ...
- .Net中的反应式编程(Reactive Programming)
系列主题:基于消息的软件架构模型演变 一.反应式编程(Reactive Programming) 1.什么是反应式编程:反应式编程(Reactive programming)简称Rx,他是一个使用LI ...
- nginx小记
上一次折腾nginx还是两年前的事情了.好多配置都忘记了. 捣腾了下阿里云,部署了一下,遇到几个小问题,温故并记录一下吧 :) 重新设置 nginx遇到问题:nginx: [error] invali ...