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 ...
随机推荐
- ADO.NET数据访问模板整理
/// <summary> /// 数据访问类:hi_test /// </summary> public partial class TestDA { public Test ...
- CSS基础篇之选择符
关系选择符 E F 包含选择符(Descendant combinator) CSS1 选择所有被E元素包含的F元素. <html> <head> <meta chars ...
- 在java中如何用键盘输入一个数,字符,字符串
一,利用 Scanner 实现从键盘读入integer或float 型数据 import java.util.*; public class test { public static void mai ...
- <2048>调查报告心得与体会
老师这次给我们布置了一个任务,就是让我们写一份属于自己的调查报告,针对这个任务,我们小组的六个人通过积极的讨论,提出了一些关于我们产品的问题,当然这些问题并不是很全面,因为我们是从自己的角度出发,无法 ...
- 玩转SQL Server复制回路の变更数据类型、未分区表转为分区表
玩转SQL Server复制回路の变更数据类型.未分区表转为分区表 复制的应用: 初级应用:读写分离.数据库备份 高级应用:搬迁大型数据库(跨机房).变更数据类型.未分区表转为分区表 京东的复制专家 ...
- 在 Azure 上使用 Docker运行 Mono
Docker 是最近相当热门的一个名词,它是一个基于 Linux Container 的轻量化的虚拟技术,而微软也相当积极与 Docker 合作,在 Azure 上支持这个火热的技术,并且提供简单的方 ...
- AnguarJS 第二天----数据绑定
Terms 今天学习AngularJS双向数据绑定的特性,这里面需要提到两个概念: 数据模型:数据模型是指 $scope对象, $scope对象是简单的javascript对象,视图可以访问其中的属性 ...
- WPF PlacementTarget技巧
<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winf ...
- 提供程序不支持 DatabaseExists
如果Oracle CodeFirst模式下要用EFProviderWrapperToolkit,那么会报告以下错误: 提供程序不支持 DatabaseExists. 这个错误是因为Oracle Cod ...
- UIColor 使用起来的坑
我们一般会用 UIColor 的RGB来生成颜色: [UIColor colorWithRed:220/255 green:220/255 blue:220/255 alpha:1.0];//这样生成 ...