iOS中数据传值的几种方式
- 值传递:基本数据类型的变量之间的数据传递
//值传递不会改变变量的值
void func(int a)
{
a = ;
} int main(int argc, const char * argv[]) {
int a = ;
func(a);
printf("%d",a);//答案为8 return ;
}
2. 指针类型之间的地址传递
//地址传递会改变变量的值
void func(int *a)
{
*a = ;
} int main(int argc, const char * argv[]) { int a = ;
func(&a);
printf("%d",a);//答案为4 return ;
}
3. 全局变量static和extern
1)static修饰的全局变量作用范围为定义变量的文件,变量存储在静态区,生命周期与程序生命一致;
2)extern只能声明变量,使作用范围扩大到整个程序文件,生命周期与程序生命一致;
4.代理设置模式的数据传值
代理模式是为了解决程序的低耦合,高内聚而产生,比如:
1)A对象做不了的事情,B对象来帮A做;
2)B对象想监听A对象的行为;
3)当A发生一些事情, 想通知B对象的时候
//A设计协议
@protocol testViewDelegate
@optional
-(void)outPut:(NSString *)theTitle;
@end
//B遵守协议
...
//B实现协议方法
...
5. 通过系统通知传值
//先发布通知 /*
name:通知名称
object:谁发出通知 nil代表匿名发布
*/
[[NSNotificationCenter defaultCenter] postNotificationName:@"note" object:nil]; //监听通知
//方式一:
/*
Observer:谁观察通知
selector:监听到通知,就会调用这个方法
name:通知名称
object:谁发出通知nil代表监听所有
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reciveNote) name:@"note" object:nil]; //方式二: /*
name:通知名称
object:谁发出通知
queue: 确定Block在哪个线程调用 队列,传入nil,block就会直接运行在发布通知线程中
usingBlock:只要监听到通知,就会自动调用这个block
*/ _observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"note" object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { NSLog(@"%@",self);
NSLog(@"%@",[NSThread currentThread]);
NSLog(@"调用了block:监听到通知");
}]; //方式三
//userInfo表示传入的数据
[[NSNotificationCenter defaultCenter] postNotificationName:@"note" object:nil userInfo:nil];
6.通过的block传递(此项重点颇多)
6.1 Block声明
// 声明:返回值(^block变量名)(参数)
void(^block)();//(无返回值无参数)
6.2 Block定义
// 定义
// 方式一:
void(^block1)() = ^(){
NSLog(@"调用block1");
}; // 调用Block,就会去查看下Block保存代码
block1(); // 方式二:block如果没有参数,可以省略()
// void(^)()
void(^block2)() = ^{ }; // 方式三:block定义中,返回值可以省略
// 类型:int(^)()
int(^block3)() = ^int{ return ;
}; //在Xcode中的快捷键是inline
6.3 Block类型
6.3.1 是对象
6.4 Block作用
6.4.1 保存代码块
6.4.2 Block:在一个类中定义,在另一个类中调用(常用), -> 传值
//在A类中定义一个block属性
@property (nonatomic ,strong) void(^block)();
//在B类中赋值
// 打电话
CellItem *item = [[CellItem alloc] init];
item.title = @"打电话";
item.block = ^{
NSLog(@"打电话");
};
//在B类方法中使用
if (item.block) {
item.block();
}
6.4.3 传值:
A -> B 顺传:定义属性
B -> A 逆传:代理(block替换代理)
//为了替代代理
//在B类中声明block属性
@property (nonatomic ,strong) void(^valueBlock)(NSString *value);
//同时在B类中使用,把值传递出去
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if (_valueBlock) {
_valueBlock(@"");
}
}
//在A类中定义block(首先拿到B类就能拿到B类传出去的值)
ModalViewController *modalVc = [[ModalViewController alloc] init];
modalVc.valueBlock = ^(NSString *value){ NSLog(@"接收到%@",value);
};
6.5 block的变量传递
6.5.1 默认局部变量在block中 是值传递
6.5.2 如果局部变量被static,__block,那么都是指针传递
6.5.3 全局变量.也是指针传递
6.6 block作为参数使用
// 计算
- (void)calculate:(int(^)(int))block;
//实现方法(把值传递出去)
- (void)calculate:(int (^)(int))block
{
_result = block(_result);
} //在另一个类中定义
CalculateManager *mgr = [[CalculateManager alloc] init]; [mgr calculate:^(int result){
// 计算
result += ;
result *= ; return result;
}];
6.7 block做为方法的返回值
//声明方法
- (CalculateManager *(^)(int))add;
//实现方法(此方法可以实现链式点语法)
- (CalculateManager *(^)(int))add
{
return ^(int value){ _result += value;
return self; };
}
CalculateManager *mgr = [[CalculateManager alloc] init];
mgr.add().add().add().add();
6.8 block内存管理:
非ARC环境:block怎么去管理内存
block没有访问外部局部变量,存放到全局区
block访问外部局部变量,block存放栈里面
只要block访问变量,是整个app都在的变量,那么肯定在全局区
在非ARC中.不能使用retain引用block,不会把放在堆里面,在非ARC中只能使用copy,才会把block放在堆里面
ARC环境:
block访问外部局部变量,block存放堆里面
可以使用strong去引用
补充:内存五大区:堆,栈,方法区,全局区,常量区
堆:手动管理内存
栈:不需要手动管理内容,代码块一过,会自动清空栈里面内存
如何判断非ARC环境:
1.重写dealloc,调用super,ARC中不能调用[super dealloc]
2.判断下是否可以调用retain,release等等
非ARC开发中注意:
1.访问属性,不要直接使用_,而是通过set,get方法去访问
2.非ARC中没有weak -> assign,strong -> retain
7 通过写数据到沙盒保存数据,再取数据(NSUserDefaults)
8 单例
iOS中数据传值的几种方式的更多相关文章
- QF——iOS中数据持久化的几种方式
数据持久化的几种方式: 一.属性列表文件: .plist文件是种XML文件.数组,字典都可以和它互相转换.数组和字典可以写入本地变成plist文件.也可以读取本地plist文件,生成数组或字典. 读取 ...
- PHP中数据类型转换的三种方式
PHP中数据类型转换的三种方式 PHP的数据类型转换属于强制转换,允许转换的PHP数据类型有: 1.(int).(integer):转换成整形2.(float).(double).(real):转换成 ...
- iOS页面间传值的五种方式总结(Delegate/NSNotification/Block/NSUserDefault/单例)
iOS页面间传值的方式(Delegate/NSNotification/Block/NSUserDefault/单例) iOS页面间传值的方式(NSUserDefault/Delegate/NSNot ...
- ASP.Net中页面传值的几种方式
开篇概述 对于任何一个初学者来说,页面之间传值可谓是必经之路,却又是他们的难点.其实,对大部分高手来说,未必不是难点. 回想2016年面试的将近300人中,有实习生,有应届毕业生,有1-3年经验的,有 ...
- iOS中拉伸图片的几种方式
假如下面的一张图片,是用来做按钮的背景图片的,原始尺寸是(128 * 112) 按钮背景图片.png 我们通过代码将这张图片设置为按钮的背景图片,假如我们将创建好的按钮的宽高设置为:(W=200, H ...
- ASP.NET MVC教程四:ASP.NET MVC中页面传值的几种方式
准备 在Models文件夹里面新添加Student实体类,用来模拟从Controller向View传递数据,Student类定义如下: using System; using System.Colle ...
- 在.net core中数据操作的两种方式(Db first && Code first)
在开发过程中我们通常使用的是Db first这种模式,而在.net core 中推荐使用的却是 code first 反正我是很不习惯这种开发模式 于是就搜寻整个微软的官方文档,终于找到了有关.net ...
- iOS中延时执行的几种方式的比较和汇总
本文列举了四种延时执行某函数的方法及其一些区别.假如延时1秒时间执行下面的方法. - (void)delayMethod { NSLog(@"execute"); } 1.perf ...
- IOS中延时执行的几种方式的比较
本文列举了四种延时执行某函数的方法及其一些区别.假如延时1秒时间执行下面的方法. - (void)delayMethod { NSLog(@"execute"); } 1.perf ...
随机推荐
- 【原创】Kakfa utils源代码分析(一)
Kafka.utils,顾名思义,就是一个工具套件包,里面的类封装了很多常见的功能实现——说到这里,笔者有一个感触:当初为了阅读Kafka源代码而学习了Scala语言,本以为Kafka的实现会用到很多 ...
- 【转载】Memcached在.Net中的基本操作
一.Memcached ClientLib For .Net 首先,不得不说,许多语言都实现了连接Memcached的客户端,其中以Perl.PHP为主. 仅仅memcached网站上列出的语言就有: ...
- Entity Framework 实体框架的形成之旅--几种数据库操作的代码介绍(9)
本篇主要对常规数据操作的处理和实体框架的处理代码进行对比,以便更容易学习理解实体框架里面,对各种数据库处理技巧,本篇介绍几种数据库操作的代码,包括写入中间表操作.联合中间表获取对象集合.递归操作.设置 ...
- 一道java算法题分析
最近在面试中遇到这样的一道算法题: 求100!的结果的各位数之和为多少? 如:5!=5*4*3*2*1=120,那么他们的和为1+2+0=3这道题不算难,不过倒是注意的细节也有 ...
- android释放内存的一个办法
step 1:定义一个监听接口 public static interface OnLowMemoryListener { void onLowMemoryReceived(); } /* 何问起 h ...
- 精品干货丨APP常用导航框架
文章目的:在整体上把握移动端App的导航框架,理解每种导航所具有的优点.局限性和其所适用的范围. 文章用心:典型APP案例(源码:http://www.jinhusns.com/Products/Do ...
- Oracle-- (RANK) 排名函数
内容来自: Oracle® Database SQL Language Reference 11g Release 2 (11.2) E41084-03. empolyees表来自hr方案. RANK ...
- Calling startActivity() from outside of an Activity
在Activity中使用startActivity()方法不会有任何限制,因为Activity重载了Context的startActivity()方法.但是如果是在其他地方(如Widget或Servi ...
- [修复] Firemonkey 画线问题(Android & iOS 平台)
问题:官方 QC 的一个 Firemonkey 移动平台画线问题: RSP-14309: [iOS & Android] Delphi 10.1 Berlin - drawing proble ...
- Firemonkey 指定 StringGrid 只能上下滾动,不要左右滚动
要使 StringGrid 只能上下滚动,不要左右滚动,只要加入下面代码即可: StringGrid1.AniCalculations.TouchTracking := [ttVertical]; p ...