iOS中数据传值的几种方式

值传递:基本数据类型的变量之间的数据传递

//值传递不会改变变量的值
void func(int a)
{
   a = 4;
}
int main(int argc, const char * argv[]) {
  int a = 8 ;
  func(a);
  printf("%d",a);//答案为8
  return 0;
}
``` 

## 指针类型之间的地址传递

```objc
//地址传递会改变变量的值
void func(int *a){
  *a = 4;
}
int main(int argc, const char * argv[]) {
   int a = 8 ;
   func(&a);
   printf("%d",a);//答案为4
   return 0;
}

全局变量static和extern

1)static修饰的全局变量作用范围为定义变量的文件,变量存储在静态区,生命周期与程序生命一致;
    2)extern只能声明变量,使作用范围扩大到整个程序文件,生命周期与程序生命一致;

代理设置模式的数据传值

代理模式是为了解决程序的低耦合,高内聚而产生,比如:
    1)A对象做不了的事情,B对象来帮A做;
    2)B对象想监听A对象的行为;
    3)当A发生一些事情, 想通知B对象的时候

//A设计协议
@protocol testViewDelegate
@optional
-(void)outPut:(NSString *)theTitle;
@end
//B遵守协议...
//B实现协议方法...

通过系统通知传值

//先发布通知
/* 
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];

通过的block传递(此项重点颇多)

  • Block声明
// 声明:返回值(^block变量名)(参数)void(^block)();//(无返回值无参数)
  • Block定义
// 定义
// 方式一:
void(^block1)() = ^(){NSLog(@"调用block1");};
// 调用Block,就会去查看下Block保存代码block1();
// 方式二:block如果没有参数,可以省略()
// void(^)()void(^block2)() = ^{};
// 方式三:block定义中,返回值可以省略
// 类型:int(^)()int(^block3)() = ^int{return 2;};
//在Xcode中的快捷键是inline
  • Block类型
    • 是对象
  • Block作用
    • 保存代码块
    • 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();}
  • 传值: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(@"123");
  }
}
//在A类中定义block(首先拿到B类就能拿到B类传出去的值)
ModalViewController *modalVc = [[ModalViewController alloc] init];
modalVc.valueBlock = ^(NSString *value){
  NSLog(@"接收到%@",value);
};

block的变量传递

  • 默认局部变量在block中 是值传递
  • 如果局部变量被static,__block,那么都是指针传递
  • 全局变量.也是指针传递

block作为参数使用

// 计算
- (void)calculate:(int(^)(int))block;
//实现方法(把值传递出去)
- (void)calculate:(int (^)(int))block{
  _result = block(_result);
}
//在另一个类中定义
CalculateManager *mgr = [[CalculateManager alloc] init];
[mgr calculate:^(int result){
// 计算
result += 5;
result *= 2;
return result;
}];

block做为方法的返回值

//声明方法
- (CalculateManager *(^)(int))add;
//实现方法(此方法可以实现链式点语法)
- (CalculateManager *(^)(int))add{return ^(int value){
_result += value;
return self;
};
}
CalculateManager *mgr = [[CalculateManager alloc] init];
mgr.add(5).add(5).add(5).add(5);

block内存管理:

  • 非ARC环境:block怎么去管理内存
    • block没有访问外部局部变量,存放到全局区
    • block访问外部局部变量,block存放栈里面
    • 只要block访问变量,是整个app都在的变量,那么肯定在全局区
    • 在非ARC中.不能使用retain引用block,不会把放在堆里面,在非ARC中只能使用copy,才会把block放在堆里面
  • ARC环境:
    • block访问外部局部变量,block存放堆里面
    • 可以使用strong去引用
    • 补充:内存五大区:堆,栈,方法区,全局区,常量区
    • 堆:手动管理内存
    • 栈:不需要手动管理内容,代码块一过,会自动清空栈里面内存
  • 如何判断非ARC环境:
    • 重写dealloc,调用super,ARC中不能调用[super dealloc]
    • 判断下是否可以调用retain,release等等
  • 非ARC开发中注意:
    • 访问属性,不要直接使用_,而是通过set,get方法去访问
    • 非ARC中没有weak -> assign,strong -> retain

通过写数据到沙盒保存数据,再取数据(NSUserDefaults)

单例

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容