为了与C语言区分OC关键字以@开头。
NSObject 是基类。单继承。支持接口(协议)@protocol 。使用接口来实现多继承。支持多态。支持抽象类。简单的异常处理 @try @catch @finally。所有函数都是虚函数。
注释 ://, /* */
布尔类型 BOOL 值为 YES 、NO 。
Id类型 OC中每个类型都可以表达为id类型,可以认为是NSObject *,void *
nil 等同于null,表示一个目标指针。
类定义
OC类分为2个文件,一个是.h 一个是.m文件
.h 文件存放类,函数申明。
.m 文件存放类的具体实现
类申明使用关键字 @interface @end 来申明。
类实现使用关键字 @implementation @end 来实现。
对象方法和类方法
如果申明和实现一个类的函数,需要使用 + 或者 – 来用在函数的开始。
+ 表示类的方法。
- 表示对象的方法。
类声明<Dog.h>
#import<Foundation/Foundation.h>
@interface Dog : NSObject {\
}
@end
类实现<Dog.m>
#import “Dog.h”
@implementation Dog
@end
不用#include可以防止重复包含。
创建/销毁 OC 对象
创建对象 Dog * dog = [ Dog alloc ];
初始化构造函数 [dog init];
销毁对象 [dog release];
类中字段和函数
@interface Dog : NSObject{
//字段定义在此处
Int age;
}
//函数定义在此
-(void)setAge(int)newAge;
@end
字段定义
三种作用域 : @public @protected @private
OC 缺省的是 @protected
OC 函数全部都是public类型(用另外方式实现private化);
变量必须定义在 类 { } 之间的地方。
类申明比较
所有OC类,接口声明必须要带 * ,这里 * 即表示指针也表示引用。
Dog * myDog; 可以通过 myDog àdog 或者 myDog.dog这些方法来访问。
函数
不带参数函数:(函数名 : f)-(int) f ;
带一个参数函数:(函数名 : f:x)-(int) f: (int)x ;
带两个参数函数:(函数名 : f: :)-(int) f:(int)x :(int)y ;
参数能够在 :前面设置一个标签label, 标签label为函数名的一部分,标签是为了方便阅读(不带标签实际上也有一个匿名标签)。
-(float) f:(int)x g:(int) y ; //g表示标签,函数名是 f:g: ;
//第一个参数不能有标签,事实上函数名就是第一个参数的标签。
函数调用
(无参函数) int ret = [ obj fool] ;
(一参函数) int ret = [ obj fool:10 ] ;
(两参函数) int ret = [ obj fool:10 :20] ;
(带标签) int ret = [obj fool:10 andB:2];
函数重载
OC不是严格的函数重载。
@interface Fool :NSObject{
}
-int g:(int)x;
-int g:(float)x;//错误,和前一个方法冲突。
@end
Message 消息机制
使用发送目标对象一个消息来达到处理函数。
使用如下格式来出来发送消息
[object message] object.message
因为是动态绑定,消息和接受者都是在运行时动态绑定在一起的。
Object 表示一个对象或者一个类。
Message 消息也可以认为是一个函数。
通过不同的参数个数,调用不同的构造;
标签:为函数名的一部分。
属性的get set 方法类似java的set get。
Self 类似 this
Dog * dog = [Dog alloc]; //声明类的引用或是指针
[Dog init]; //调用构造初始化属性的值
Int ID = [gog.getID]; //调用对象的方法getID.
同样使用 printf(“%d %f %c %s”,a,b);等进行格式化输出。
点语法
属性可以在不适用括号的情况下使用点语法。
无需调用 [foo value] 可以使用foo.value 来访问。虽然foo.value看起来像是直接调用value变量,但是属性始终调用方法,而这些方法又可以访问对象的数据。
例如:Dog.h头文件的申明
@interface Dog : NSObject {
Int age;
}
-(void)setAge:(int)newAge ;
-(int)age;
@end
Dom.m的实现
#import “Dog.h”
@implementantion Dog
-(void)setAge:(int)newAge{
age=newAge;
}
-(int)age{
Return age ;
}
@end
类的setter 和getter 函数
-(void) setAge:(int)newAge ;
-(int)age;
类似于setAge:设置新值一般叫做setter函数。
类似于 age取值一般叫做getter 函数。
使用经典调用和点语法
Dog * dog = [ [Dog alloc ] init ] ;
[dog setAge : 100] ;
Int dogAge = [dog age] ;
NSLog(@” Dog new Age is %d”,dogAge);
点语法
dog.age = 200; //调的age是属性age
dogAge = dog.age;//调的age 是方法age
NSLog(@” Dog new Age is %d”,dogAge );
点语法是编译器级别
dog.age = 200;
dogAge = [dog age]; 编译器会把dog.age = 200;展开成[dog setAge:200];
会把dogAge = dog.age; 展开成dogAge = [dog age]; 函数调用。
点语法setter和getter规范
setter函数展开规范
dog.age = 200;-----------------[dog setAge:200] ;
getter函数展开规范
int dogAge = dog.age;------------------int dogAge = [dog age];
@property
@property是让编译器自动产生函数申明,
不用在写下面两行了:
-(void) setAge:(int)newAge ;
-(int)age ;
只需下面一行就可以代替:@property int age ;
@interface Dog : NSObject {
Int age;
}
@property int age ;
//-(void)setAge:(int)newAge ;
//-(int)age;
@end
@synthesize
@synthesize就是编译器自动实现getter和 setter函数。
不用写下列代码
-(void) setAge: (int) newAge{
age=newAge;
}
-(int)age{
Return age;
}
只需要写: @synthesize age ;
#import “Dog.h”
@implementantion Dog
@sybthesize age ;
/*
-(void)setAge:(int)newAge{
age=newAge;
}
-(int)age{
Return age ;
}*/
@end
@property的进一步说明(如何区分字段名和函数名重复的问题)
@interface Dog : NSObject{
Int _age ; // age前面加一个下划线。
}
@property int age;
@end
@implementation Dog
@synthesize age = _age ; //目的是避免函数名和字段名重复
@end
@property的属性
1、readwrite(缺省),readonly :表示属性是可读写的,也就是可以使用getter和setter,而readonly只能使用getter。
2、assign(缺省值),retain,copy:表示属性如何存储。
3、nonatomic :表示不考虑线程安全的问题。默认字段都是被加锁的
4、getter=...,setter=... :重新设置getter函数和setter函数名。
例如:age属性只读 @property (readonly) int age ;
内存管理的黄金法则
如果对一个对象使用了allocation,[mutable]copy,retain,那么你必须使用相应的release 或者autorelease.(我的理解 :开辟了内存总归要释放);
内存管理 ---- 类型定义
1、 基本类型 任何的C类型,如 int ,short,char,long,struct,enum,union等。
2、 内存管理对于C语言基本类型无效。
3、 OC类型(非基本类型)。
4、 任何继承与NSObject类的对象搜属于OC类型。
OC对象结构
如图所示所有的OC对象都有一个计数器,保留着当前被引用的数量。
内存管理对象
OC的对象:非基本对象(int ,short,struct)
NSObject:凡是继承于NSObject的每一个对象都有一个retainCount计数器(4个字节)。表示当前的引用被应用的次数。如果计数为0,那么就是真正的释放这个对象。
alloc retain release 函数
OC中 alloc 函数是创建对象使用,创建完成后计数器为1。只用一次。
retain 是对一个对象的计数器 +1 。可以调多次。
release 是对一个对象计数器 -1 。减到0对象就会从内存中释放。
OC内存管理
Objective---C类中实现来了引用计数器,对象知道当前被引用的次数。
最初对象的计数器是1.
如果需要引用对象,可以给对象发送一个retain消息,这样对象计数器就加1.
当不需要引用对象了,可以给对象发送release消息,这样对象计数器就减1.
当计数器减到0,自动调用对象的dealloc函数,对象就会释放内存。
计数器为0 的对象不能在使用release和其他方法。
retain/release例子
NSMutableString * str = [[NSMutable alloc] iniit ]; //str计数器为1
[str retain]; //str计数器为2
[str retain]; //str计数器为3
[str release]; //str计数器为2
[str release]; //str计数器为1
[str release]; //str计数器为0,对象释放内存。
人遛狗程序:Person Dog
-----------------------------------------------------------------------------------------
#import <Foundtion/Foundation.h>
@interface Dog : NSObject{
Int _ID;
}
@property int ID ;
#import “Dog.h”
@implementation Dog
@synthesize ID = _ID ;
-(void) dealloc{
NSLog(@”dog %d is dealloc”,_ID);
}
#import <Foundtion/Foundation.h>
#import “Dog.h”;
@interface Person :NSObject{
Dog * -dog;
}
-(void) setDog:(Dog *)aDog ;
-(Dog *)dog;
#import “Person.h”
@implementation Person
-(void) setDog:(Dog *)aDog {
If(aDog !=DOG){ //两个狗不等
_dog = aDog;
[_dog retain]; //让_dog计数器 +1 ,两句可以合为 –dog = [aDog retain];
}
}
-(Dog *)dog{
Reutrn _dog;
}
-(void)dealloc{
NSLog(@”person %d is dealloc!”);
[_dog release]; //把人拥有的_dog释放
[super dealloc];
Int main(int argc,const char * argv[]){
@autoreleasepool{
NSLog(@”Hello world!”);
//创建一个狗的实例
Dog * dog1 =[[Dog alloc] init]; //1
[dog1 setID:1];
//创建人的实例
Person * xiaoli = [[Person alloc] init];
Person * xiaowang = [[Person alloc] init];
//xiaoli这个人要遛狗
[xiaoli setDog:dog1]; //2
//xiaowang这个人要遛狗
[xiaowang setDog:dog1]; //3
//打印当前dog1的引用数量 3
NSLog(@“dog1 retain count is %d ”,[dog1 retainCount]);
[dog1 release]; //2
NSLog(@“dog1 retain count is %d ”,[dog1 retainCount]);
[xiaoli release]; // 1
NSLog(@“dog1 retain count is %d ”,[dog1 retainCount]);
}
return 0;
}
----------------------------------------------------------------------------------------------
OC内存管理和点语法
OC内存管理正常情况要使用大量的retain和release操作。
点语法可以减少使用retain和release的操作。
Person.h头文件的申明
@interface Person :NSObject{
Dog * _dog;
}
@property (retain) Dog * dog ;
@end
Person.m实现文件
@implementation Person
@synthesize dog = _dog;
-(void)dealloc{
self.dog = nil;
[super dealloc];
}
@end
@property展开(retain属性)
@property (retain) Dog * dog ;
展开为:
-(void)setDog:(Dog *) aDog ;
-(Dog *) dog;
@synthesize(retain属性)
@synthesize dog = _dog ;
展开为:
-(void)setDog:(Dog *) aDog {
If(_dog != aDog){ //上一次的_dog和新的aDog比较
[_dog release];
_dog = [aDog retain];
}
}
-(Dog *) dog{
Return _dog;
}
dealloc 必须要释放dog(retain)
-(void)dealloc{
Self.dog = nil; //会调用setDog :(Dog *) aDog;只不过传的值是nil
[super dealloc];
}
copy属性
copy属性是完全把对象重新拷贝一份,计数器从新设置为1,和之前拷贝的数据完全脱离关系。
@property (copy) NSString * str;
//表示属性的getter函数
-(double) str{
Return str;
}
//表示属性的setter函数
-(void)setStr:(Nstring *)newStr{
Str = [newStr copy];
}
assign,retain,copy
foo = value; //简单引用赋值
foo = [value retain]; // 引用赋值,并且增加value的计数器
foo = [value copy]; //将value 复制了一份给foo,foo和value就毫无关系
NSMutableArray典型用法
NSMutableArray * array = [[NSMutableArray alloc] init];
For(int i = 0;i<10;i++){
Dog * dog = [[Dog alloc] init]; //实例化一个狗对象
[dog setID:i] ; //为狗对象的ID赋值
[array addObject:dog] ; //将这个狗对象加入array中
[dog release]; //释放掉狗对象,实际是retainCount -1
}
For(Dog * d in array){
NSLog(@”dog is %d:”,[id ID]);
}
[array release];
#import <Foundation/Foundation.h>
@interface Dog :NSObject{
Int _ID;
}
@property (assign) int ID;
@end
#import “Dog.h”
@implementation Dog
@synthesize ID = _ID ;
-(void)dealloc{ //当对象计数器为0是自动会调该方法。
NSLog(@”dog id %d dealloc:”,_ID);
[super dealloc];
}
@end
Int main(int argc,const char * argv[]){
@autoreleasepool{
//创建一个数组
NSMutableArray * array = [[NSMutableArray alloc] init];
//创建几条狗的实例
For(int i=0;i<4;i++){
Dog * d = [[Dog alloc] init];
//将Dog实例放入数组
[array addObject:d];
//释放Dog实例
[d release];
}
[array release]; //释放数组中的所有Dog实例对象,会分别掉dealloc
}
自定义数组MyArray
@inerface MyArray:NSObject{
NSUInteger _count; //数组中当前有几项
Id _objs[512]; //创建一个512项的数组4*512
}
@property (assign,readonly ) BSUInteger count;
//往MyArray中加入一项元素
-(voido) addObject : (id)object;
//取得第Index项元素
-(id)objectAtIndex:(NSUInteger)index;
//删除第index项元素
-(void) removeObjectAtIndex: (NSUInteger) index;
//删除所有的元素
-(void) removeAll;
#import “MyArray.h”
@implementation MyArray
@synthesize count = _count;
-(id) init{
self = [super init];
if(self){
_count = 0;
}
Return self;
}
//往MyArray中加入一项元素
-(voido) addObject : (id)object{
If(_count >=512){
Return;
}
_objs[_count] = [object retain];//这里必须是retain
_count++;
}
//取得第Index项元素
-(id)objectAtIndex:(NSUInteger)index{
Return _objs[index];
}
//删除第index项元素
-(void) removeObjectAtIndex: (NSUInteger) index{
Id obj = _objs[index];
[obj release];
_objs[index] = nil;
}
//删除所有的元素
-(void) removeAll{
For(int i=0;i<_count;i++){
[self removeObjectAtIndex : i];
}
}
-(void) dealloc{
[self removeAll];
[super dealloc];
}
Objective-C自动释放池
自动释放池(Autorelease Pool)是Objective-C的一种内存自动回收机制,可以将一些临时变量通过自动释放池来回收统一释放。
挡自动释放池本身销毁的时候,池子里面所有的对象都会做一次release操作。
autorelease
任何OC对象只要调用autorelease方法,就会把该对象放到离自己 最近的自动释放池中(栈顶的释放池);
创建自动释放池
//IOS 5.0新方式
@autoreleasepool{
}
@end
//IOS5.0之前
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[pool release];
自动释放池应用
//普通的方式
Int main (int argc ,const char * argv[]){
NSAutoreleasePool * pool = [[NSAutoreleasePool alooc] init];
Person * xiaoli = [[Person alloc] init];
Dog * dog1 = [[Dog alloc] init];
Xiaoli.dog = dog1;
[dog1 release];
[xiaoli release];
[pool release];
}
//普通的方式
Int main (int argc ,const char * argv[]){
NSAutoreleasePool * pool = [[NSAutoreleasePool alooc] init];
Person * xiaoli = [[Person alloc] init];
Dog * dog1 = [[[Dog alloc] init] autorelease];//把dog1放入自动释放池中,dog1的retainCount=1
Xiaoli.dog = dog1; // dog1的retainCount=2
// [dog1 release];
[xiaoli release]; // dog1的retainCount=1
[pool release]; // 池子销毁dog1对象也就释放了
几个错误的例子
(1)//两个点坐标相加
-(Point2D *) add: (Point2D *) p1 and:(Point2D *)p2 {
Point2D * result = [[Point2D alloc] init];
result.x = p1.x + p2.x;
result.x = p1.y + p2.y;
return result;
}
/该函数使用了alloc,创建了对象并且计数器为1,根据黄金法则他应该使用release来释放。
改正如下:
//两个点坐标相加
-(Point2D *) add: (Point2D *) p1 and:(Point2D *)p2 {
Point2D * result = [[Point2D alloc] init];
result.x = p1.x + p2.x;
result.x = p1.y + p2.y;
[result autorelease]; //放入自动释放池中,等会在释放
return result;
}
(2)//寻喊中产生大量OC对象的处理
For(int index ;index <100000 ; index ++){
NSMutableString * str = [[NSMutableString alloc] init];
[str autorelease];
}
//创建了1000000个对象都放入的自动释放池,占用大量内存显然性能不好。只有当自动释放池销毁是这大量的OC对象才会被销毁。
改正:
NSAutoreleasePool * pool ;
Pool = [[NSAutoreleasePool alloc] init];
For(int index ;index <100000 ; index ++){
NSMutableString * str = [[NSMutableString alloc] init];
[str autorelease];
If(index % 1000 == 0){
[pool release];
Pool = [[NSAutoreleasePool alloc] init];
}
}
[pool release];
//改程序每当执行1000次就会销毁一次自动释放池,然后重建。所以池子里的对象永远不会超过1000个。
什么是协议
协议是多个对象之间协商的一个接口对象。
协议提供一系列方法用来在协议的实现者和代理者之间的一种通信方式。
协议类似于C++中的虚函数,或者是java 中的接口。
协议的声明
@protocol MyProtocol <NSObject>
//要定义的变量
-(void) init ;
-(int) update: (int) time;
@end
协议
Protocol 声明一系列的方法,这些方法放在实现的Protocol中实现。
协议方法可以实现optional ,可选实现:
@required 必须实现的方法。
@optional 可选的方法,可以实现也可以不实现。
协议需要继承与 基协议NSObject
协议可以多继承
@protocol MyProtocol <NSObject>
//要定义的变量
@optional
-(void) init ;
-(void) exit;
@required
-(int) update: (int) time;
@end
简单协议的例子
//协议的定义
@protocol MyProtocol <NSObject>
-(void)showinfo;
@end
//协议的使用
@interface MyTest :NSObject<MyProtocol>
-(void) showinfo2;
@end
//协议的实现
@implementation MyTest
-(void) showinfo{
NSLog(@”log file”);
}
-(void) showinfo2{
NSLog(@”log file2”);
}
@end
Int main(int argc, const char * argv[]){
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Id<MyProtocol> test = [[MyTest alloc] init]; //id是反省指向协议
[test showinfo];
[test showinfo2]; //id仍然可以响应showinfo2消息
[pool drain];
return 0;
}
判断某个对象是否响应方法
既然接口可以部分实现,OC对象提供了动态判断某个方法是否实现的方法。
respondsToSelector
if([test respondsToSelector:@selector(showinfo)]){
[test showinfo];
}
-(BOOL) dowork{
If([test respondsToSelector:@selector(showinfo)]){
[test showinfo];
return YES;
}
return NO;
}
例子
//定义协议
#import <Foundation/Foundation.h>
@protocol MyProtocol <NSObject>
@optional
-(void) print: (int) value;
@required
-(int) printValue: (int)value1 andValue: (int) value2;
@end
//声明类使用协议
#import <Foundation/Foundation.h>
@interface MyTest :NSObject<MyProtocol>
-(void)showinfo
@end
//实现协议
#import “MyTest.h”
@implementation MyTest
//类中定义的方法
-(void)showinfo{
NSLog(@”showinfo is calling”);
}
//必须实现的协议方法
-(void)printValue: (int)value1 andVslue: (int)value2{
NSLog(@”print value value1: %d value2 %d”,value1,value2);
return 0;
}
//不一定要实现的协议方法
-(void)print: (int)value {
NSLog(@”print value %d”,value);
}
@end
Int main(int argx,const char * argv[]){
@autoreleasepool{
MyTest * myTest = [[MyTest alloc] init];
[myTest showinfo];
//[myTest print:20];
[myTest printValue:10 andValue:21];
//判断方法是否实现
SEL sel = @selector(print:); //将print:转化成SEL类型的方法。所有OC方法都可以转化为SEL类型
If([myTest respondsToSelector:sel]){ //判断MyTest是否实现print方法
[myTest print:20];
}
[myTest release]
//用协议的方式
Id<MyProtocol> myProtocol = [[MyTest alloc] init];
If([myProtocol respondsToSelector:@selector(print:)]){
[myprotocol print:103];
}
}
return 0;
}
//协议代理设计模式
//定义一个任何狗通信的范式 protocol.
@procotol DogBark<NSObject>
-(void) bark : (Dog *)thisDog count : (int) count;
@end
//定义一条狗
@interface Dog:NSObject{
NSTimer * timer; //定时器
Int barkCount; //叫的次数
Int _ID;
Id< DogBark > delegate ; //狗的主人
}
@property int ID;
@property (assign)id< DogBark > delegate;
@end
@implementation Dog
@synthetype ID = _ID;
@synthesize delegate ;
-(id) init{
self = [super init];
If(self){
· timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES ];
//创建一个定时器,每隔1.0s就调用[ self updateTimer:nil ];
}
Return self;
}
-(void) updateTimer: (id)arg{
barkCount++;
NSLog(@”dog bark %d”,barkCount);
//通知狗的主人
[delegate bark:self count:barkCount]; //调用delegate里面的bark:count:方法
}
@end
//定义一个人
@interface Person:NSObject< DogBark >{
Dog * _dog;
}
@property Dog *dog;
@end
@implementation Person
@synthetype dog = _dog;
-(void)setDog : (Dog *) dog{
If(_dog != dog){
[_dog release];
_dog = [dog retain];
//通知 _dog的主人是self
[_dog setDelegate:self];
}
}
-(Dog *) dog{
Return _dog;
}
-(void) bark : (Dog *)thisDog count: (int) count{
//当狗叫时调用人的方法
NSLog(@”this dog %d bark %d”,[thisDog ID],count);
})
-(void) dealloc{
Self.dog = nil;
[super dealloc];
}
@end
Int main(int argx,const char * argv[]){
@autoreleasepool{
Person * xiaoli = [[Person alloc] init];
Dog * dog = [[Dog alloc] init];
[dog setID:10];
While(1){
[[NSRunLoop currentRunLoop] run];
}
[xiaoli setDog:dog];
[dog release];
[xiaoli release];
}
}
类别Category
Category能把一个类的实现分为若干不同的文件中。每个Category 是类的一部分。
类的不同类别可以单独编译(可以让不同开发者负责一个Category)。
如果把一个类Category(申明和实现)放到一个.m文件中,那么该Category外界不能访问。这样实现了类似C++中class的private功能。
Category实际上就是对类的扩展。
类别Category 的缺点
类别Category只能扩展函数,消息,不能扩展字段,变量等。
类别Category命名规范
一般Category命名为:要扩展的类名 +扩展变量.[hm].
比如:NSString +ReverserString.h NSString +ReverserString.m
UIImageView+WebCache.h UIImageView+WebCache.m
NSString+Reverse.h头文件
#import<Foundation/Foundation.h>
@interface NSString(reverse)
-(NSString *)reverseString ; //要在NSString中扩展的方法
@end
#import “NSString+Reverse.h”;
@implementation NSString(reverse)
-(id) reverseString{
NSUInteger len = [self length];// self字符串本身
NSMutableString * retStr = [NSMutableString stringWithCapacity:len];//创建空字符串
While(len > 0){
Unichar c = [self characterAtindex:--len];//取最后一个字符
NSString * str =[NSString stringWithFormat:@”%C”,c];
[retStr appendString:str]; //拼接到retStr
}
Return retStr;
}
@end
Int main( int argc,const char * argv[]){
@autoreleasepool{
NSString * string = “郭艳璐不算是好人”;
NSString * retString = [string reverseString];
NSLog(@”ret string : %s”,retString);
}
Return 0;
}
类别Category实现函数私有化
@interface A (private)
-(void)test2; //A实现的test2方法对外是不可见的。
@end
@implementation A
-(void) test{
[self test2];
}
-(void) test2{
NSLog(@”test2 is calling”);
}
@end
什么是Blocks
Block是一个C Level的语法以及运行时的一个特性,和标准C中的函数(函数指针)类似,但是器运行需要编译器和运行时支持,从IOS4.0开始就很好的支持Block.
C函数指针和Blocks申明的比较
Int (* CFunc) (int a)
返回值 变量名 参数类型 参数值
Int (^ BFunc) (int a)
C函数指针和Blocks调用
Int (* CFunc)(int a) 函数调用 int ret = CFunc(100);
Int (^ BFunc) (iint a) 函数调用 int ret = Bfunc(100);
Blocks typedef定义
C语言函数指针typedef : typedef int (* Su,BlockT) (int a,int b);
Blocks typedef 定义: typedef int (^SumBlockT) (int a, int b);
__block关键字
一个Block的内部是可以医用自身作用域外的变量的。包括static变量,extend变量或自由变量,对于自由变量,在Block中是只读的。在引入block的同时还引入了一种特殊的__block关键字变量存储修饰符。(我认为__block类似static)
typedef int(^SumblockT) (int a,int b);
Int main( int argc,const char * argv[]){
@autoreleasepool{
void (^myblocks) (void) = null; //blocks声明
myblocks = ^(void){
NSLog(@”in blocks”);
};//给myblocks赋值
NSLog(@”before blocks”);
Myblocks(); //调用或执行myblocks
NSLog(@”after blocks”);
//定义myblocks2
Int (^myblocks2) ( int a,int b) = ^(int a,int b){
Int c = a+b;
return c;
};
NSLog(@”beforr blocks2”);
Int ret = myBlocks2(10,20);
NSLog(@”after blocks2 ret %d”,ret);
//定义blocks3
__block Int sum = 0;//强制是sum成为一个全局数据。
Int (^myblocks3) (int a,int b) = ^(int a,int b){
Sum = a+b;
Return 3;
};
NSLog(@”sum is %d”,sum);
SumblockT myblocks4 = ^(int a,int b){
NSLog(@”sum is %d”,a+b);
Return 0;
}
myblocks4(10,20);
}
return 0;
}