`
zyallday
  • 浏览: 26790 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

Objective-C Block数据类型讲解

阅读更多
转自:http://kan.weibo.com/con/3516583830745467

/**

用来内存管理第一部分的测试函数

@param value1 第一个整型值

@param num2 第二个参数

*/

int _testBlock(constint value1,int num2);

int _testBlock(constint value1,int num2)

{

   return value1 + num2;

}

int main(int argc, constchar * argv[])

{

   //Block 数据类型

   //1、声明Block 数据类型变量

   int num1 = 7;

   /**

   Block 数据类型与结构体类型相似指的都是泛指类型的数据类型,即需要声明具有实际意义的Block数据类型或结构体类型

  

       int(^aBlock)(int num2),第一个int指的是当前Block数据类型的返回值的类型是整型,可以换成其他数据类型,^aBlock在小括号内表示的数据类型为aBlock,第二个int num2即为参数

  

       ^(int num2){

  

           return num1+num2;

       }; 赋值运算符的后边,即为Block变量的值,大括号内是函数实现的逻辑,即可以随意更改为其他逻辑,例如return num1 * num2等等;

    */

   int(^aBlock)(int num2)  = ^(int num2){

      

       return num1+num2;

   };

  

   //同样可以通过类型定义,定义具体的Block数据类型,下面即定义一个返回值为整型,只有一个整型参数的myBlock数据类型

   typedefint(^myBlock)(int num2);

  

   //可以通过myBlock数据类型声明变量

   myBlock bBlock = ^(int num2){

       return num1 - num2;

   };

   //使用第一种方式定义的Block变量

   NSLog(@"aBlock = %d",aBlock(3));

   //使用第二种方式定义的Block变量

   NSLog(@"bBlock = %d",bBlock(3));

  

  

  

  

   //2、Block 变量涉及到的内存问题

   int value1 = 2;

   //定义具体的Block数据类型CaculateBlock

   typedefint(^CaculateBlock)(int num2);

   CaculateBlock _block = ^(int num2){

       //value1++是不可以改变的

       //在Block变量的内部,使用外部的变量时是只读的

       return value1 + num2;

   };

   /**

   重新修改valu1的值,结果等于4 而不是5

      

       我们可以通过另外一种方式理解,再main函数外定义一个函数 int _testBlock(const int value1,int num2);

    */

   //想想为什么_testBlock一定要在上边调用?

   NSLog(@"_testBlock = %d",_testBlock(value1,2));

   value1 = 3;

   NSLog(@"_block = %d",_block(2));

  

   //怎么解决这种问题只读变量的问题呢,使用__block关键字

  

   __blockint value2 = 2;

   CaculateBlock _block2 = ^(int num2){

       value2 ++;

       return value2 - num2;

   };

   value2++;

   //4-3 = 1,value2是怎么变成4的呢,很明显是value2的两次自增变化的

   NSLog(@"_block2 = %d",_block2(3));

  

   //总结内存问题,就是几句话,每一个Block变量是存储在一个栈区stack1(因为是局部变量的原因),但是因为每一个Block变量的值是一段代码块,所以Block变量的值自己也负责管理一片栈区stack2的内存,当Block变量出栈后,Block变量的值自己负责的栈也会自动出栈。

   //那么声明Block数据类型的变量的过程中,使用外部变量的时候,使用__block关键字的话,该外部变量可以理解为一个小型的全局变量,但是全局仅限于Block变量中使用,否则不使用__block关键字的话,在声明Block数据类型时,是将该外部变量的值赋值到Block变量自己负责的栈区内,并设置为const只读变量,所以及时修改了外部变量的值,仍然不会影响到Block自己负责的栈区的只读变量的值,因为它们已经是两片内存区域了。

  

   //3、由于使用Block引起的retain cycle即循环持有的问题.

   //举例,封转一个学生类FOStudent

   /**

       //定义一个具体的Block数据类型

       typedef int(^StudentBlock) (int _age);

  

       @interface FOStudent : NSObject

  

       //实例属性要写copy,使用copy关键字的作用就是将任意一片内存区域的内容,赋值相同的一份到堆内存

       @property (nonatomic ,copy) StudentBlock block;

  

       //年龄,一个测试属性

       @property (nonatomic ,assign) int age;

  

       @end

  

       @implementation FOStudent

       @synthesize block;

       @synthesize age;

       - (void)dealloc

       {

           //在delloc中,在控制台打印delloc消息,提示我们该实例对象已被销毁

           NSLog(@"%s",__FUNCTION__);

           self.block = nil;

           self.age = 0;

           [super dealloc];

       }

  

       @end

    */

  

   //实例化学生对象

   FOStudent *student = [[FOStudentalloc] init];

  

   StudentBlock _studentBlock = ^(int _age){

       return student.age + _age;

   };

   //设置student的block实例属性为刚刚声明的_studentBlock局部变量,因为实例属性使用的是copy关键字,所以局部变量_studentBlock会赋值到堆内存中,并且生命周期与student实例对象相同(因为是在dealloc中释放的实例对象block内存),

   student.block = _studentBlock;

   //当对student实例对象发送release消息后,发现并没有delloc内容在控制台输出

   [student release],student = nil;

  

   //说明student实例对象并没有销毁内存,到底是在哪里它的引用计数器又加1了呢,根据第二部分的理解,声明Block变量的过程中,如果使用到的外部变量没有使用__block关键字,是会拷贝一份到Block变量自己负责的栈区,同理,在OC对象作为外部变量使用到Block变量中的时候,会对该对象的引用计数器+1,并且是在出栈的时候引用计数器-1,因为该block变量已经作为student实例对象的属性与student的声明周期相同,结果student对象不销毁,block不销毁,block不销毁,也就不会出栈,结果造成了retain cycle问题.

   //怎么解决问题呢?

   //仍然是使用__block关键字,因为__block关键字会定义小型的全局变量

  

   FOStudent *_student = [[FOStudentalloc] init];

   __blockFOStudent *bStudent = _student;

  

   StudentBlock _bstudentBlock = ^(int _age){

       return bStudent.age + _age;

   };

   _student.block = _bstudentBlock;

   //这样通过这种方式的输出,_student对象就可以销毁了,并且也在控制台进行了输出

   [_student release],_student = nil;

   return0;

}
分享到:
评论

相关推荐

    objective-c编程 第2版=objective-c program 2nd edition_13889311

    1. **基础语法**:学习Objective-C首先需要了解它的基本语法,包括变量定义、数据类型、运算符、流程控制语句等。此外,还会涉及Objective-C中的特殊语法,如nil和NULL的区别、实例变量和属性的使用。 2. **类与...

    Objective-C语言教程与案例.zip

    3. **Foundation框架**:Objective-C的基础库,提供了许多基本的数据类型和常用功能。例如,NSArray、NSDictionary、NSString等重要类的使用可能会被深入讨论。 4. **内存管理**:Objective-C使用引用计数...

    0基础iOS开发学习计划Objective-c语言内容概述.doc

    Objective-C的数据类型大部分沿用了C语言中的数据类型,如整型(`int`, `long`, `short`)、浮点型(`float`, `double`)等。此外,还有一些特殊的类型,如`NSString`、`NSArray`等用于处理字符串和数组等对象。 - ...

    Learn Objective-C On The Mac(英文PDF+SourceCode)

    2. **基本语法**:讲解Objective-C的基础语法,如变量声明、常量定义、数据类型、流程控制(条件语句和循环)等。 3. **Objective-C的对象和类**:深入讨论面向对象编程的核心概念,如类的定义、实例化、继承、多态...

    Objective-C 2.0 程序设计(中文版)+英文原版

    8. **Foundation框架与AppKit/UIKit**:Objective-C开发中常用的Foundation框架提供了基本的数据类型和系统服务,而AppKit(macOS)和UIKit(iOS)则提供了图形用户界面的组件和功能。 9. **Cocoa与Cocoa Touch**:...

    Objective-C基础教程.rar

    在学习Objective-C时,你需要了解C语言的基本概念,如变量、数据类型、控制结构等。同时,Objective-C引入了消息传递机制,这是其面向对象特性的核心。相比于C,Objective-C更注重对象间的通信,通过发送消息来调用...

    Objective-C.2.0程序设计(中文版) 高清PDF

    Objective-C是C语言的超集,这意味着你可以编写任何有效的C语言代码,同时还能利用Objective-C提供的面向对象特性。它的核心概念包括类、对象、消息传递和协议。类是对象的蓝图,定义了对象的属性和行为;对象则是类...

    Programming in Objective-C - 6th Edition

    - **变量与数据类型**:介绍Objective-C中的基本数据类型,包括整型、浮点型等;讲解变量的声明和初始化方法。 - **控制结构**:学习条件语句(如if-else)、循环语句(如for、while)及跳转语句(如break、...

    Objective-C基础教程随书源码 Learn Objective-C Samples

    7. **Foundation框架**:Objective-C的基础库,提供基本的数据类型、集合类(如NSArray、NSDictionary)、线程管理等功能。 8. **UIKit框架**:iOS开发中用于构建用户界面的主要框架,包括UI控件、事件处理等。 9....

    Programming in Objective-C 4th Edition

    书中深入讲解了Objective-C的语法结构,包括变量、数据类型、控制结构、函数、指针等基础知识。此外,还重点阐述了Objective-C特有的特性,如动态消息传递、协议、属性、块(block)等,这些特性是理解和掌握...

    Programming in Objective-C 2.0 第二版

    其次,书中的内容涵盖Foundation框架,这是Objective-C开发中的基础库,包含了诸如字符串、数组、字典等基本数据类型以及文件操作、网络通信等功能。读者将学习如何使用这些工具进行实际编程。 再者,本书还会介绍...

    objective-c教程

    在Objective-C中,数据类型、书写规范和格式符都是基础知识。学习者需要掌握不同数据类型(如基本数据类型、指针类型等)以及如何在代码中正确使用它们。书写规范涉及代码的排版和风格,有助于维护和理解代码。格式...

    Programming+in+Objective-C+2.0

    Objective-C的语法基于C语言,这意味着学习Objective-C首先要熟悉C语言的基本语法,包括变量、数据类型、控制结构等。Objective-C增加了消息传递机制,这是其面向对象特性的核心。通过发送消息给对象,可以调用对象...

    Objective-C基础教程

    Foundation框架提供了基础的数据类型、集合类和网络支持,而UIKit框架则包含了用于构建用户界面的所有元素。 10. **Xcode集成开发环境** Xcode是Apple官方的开发工具,包含了编写、调试和打包Objective-C应用所需...

    《Objective-C 编程 第6版》英文零售版

    3. **Foundation框架**:Objective-C的重要库之一是Foundation框架,它提供了大量基础数据类型、集合类以及系统服务。书中会介绍NSArray、NSDictionary、NSString等常用类的使用方法。 4. **Cocoa和Cocoa Touch**:...

    Objective-C程序设计最新版(高清中文书签)

    7. **Foundation框架**:这是Objective-C的基础库,提供了许多常用的数据类型和操作,如字符串、集合、文件系统操作等。 8. **Core Foundation**和**Cocoa Touch**:Core Foundation是C语言的底层框架,而Cocoa ...

    Effective Objective-C 2.0

    1. **理解Objective-C的基础概念**:这部分内容旨在帮助读者熟悉Objective-C的基本语法结构,包括变量定义、数据类型、运算符等基础知识。 2. **面向对象编程(OOP)的核心原则**:书中详细介绍了继承、封装、多态性等...

Global site tag (gtag.js) - Google Analytics