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 ...
随机推荐
- python pickle和json的区别
pickle可以在python之间进行交互 json可以实现python与不同开发语言的交互 pickle可以序列化python中的任何数据类型 json只能序列化python中的常归数据类型(列表等 ...
- 移动前端不得不了解的html5 head 头标签
本文主要内容来自一丝的常用的 HTML 头部标签和百度FEX的HTML head 头标签. 移动端的工作已经越来越成为前端工作的重要内容,除了平常的项目开发,HTML 头部标签功能,特别是meta标签 ...
- Python3.5+selenium操作Chrome浏览器
1.安装selenium 命令提示符下输入: pip install selenium 2.下载chromedriver 点击下载 3.将解压后的chromedriver.exe放到chrome浏览器 ...
- python 中使用 global 引发了莫名其妙的问题
哪里出问题了 python 中,使用 global 会将全局变量设为本函数可用.同时,在函数内部访问变量会先本地再全局. 在嵌套函数中,使用 global 会产生不合常理的行为. 上代码: In [9 ...
- 安装windows server 2012 r2 的那点事儿
windows server 2012 r2 安装无法找到install.wim 错误代码0x80070026,以及制作U启动盘决解ISO文件超过5G大小限制的解决方案 用UltaISO刻录后,sou ...
- Pyserial操作串口
pySerial 介绍 封装了串口通讯模块,支持Linux.Windows.BSD(可能支持所有支持POSIX的操作系统),支持Jython(Java)和IconPython(.NET and Mon ...
- SQL Server差异备份的备份/还原原理
SQL Server差异备份的备份/还原原理 记住一点:差异备份是基于最后一次完整备份的差异,而不是基于最后一次差异的差异 备份过程: 1-完整备份之后有无对数据库做过修改,如果有,记录数据库的最 ...
- 简单的jQuery幻灯片实现
一.一些抱怨 自从国庆放假上班以来,又是忙碌的工作直到现在,但是说忙好像也没有加几天班,只是上班的时候工作排的挺满.但是别人貌似一直都不太忙(也是我自己觉得),感觉就很不爽. 我喜欢快速做完一件事,然 ...
- SSRS(rdl报表)分页显示表头和对表头的冻结处理
基础环境 最近在公司做西门子某系统的二次开发,需要用到SQLServer Reporting Services(SSRS).我们用的SQL版本是SQLServer 2008 R2:在设计报表时,表格用 ...
- JavaScript面试时候的坑洼沟洄——逗号、冒号与括号
看完了javaScript数据类型和表达式与运算符相关知识后以为可以对JavaScript笔试题牛刀小试一把了,没想到有一次次的死在逗号,冒号和括号上,不得已再看看这几个符号吧. 逗号 逗号我们常见的 ...