涉及语法:block
Apple 在c,objective-c,c++ 加上block这个延伸用法。
Apple有一个叫做GCD(Grand Central Dispach)的新功能。用在同步处理的环境下右更好的效果。Block语法产生的动机就来自于GCD:用Block包好一个工作量交给GCD,CGD有一个宏观的视野可以来分配CPU,GPU,Memory。下最好的决定。
block其实行为和foundation很像,最大的差别是在可以存取同一个区域的变量。
^(传入参数列表){行为主体};
用法:
int result = ^(int a){return a*a;}(5);
block pointer:()
块指针的声明:回传值(^ 名字)(参数列); int (^ square)(int);
square =^(int a){return a*a;};
int result = square(5);
块指针也可以当做参数传给一个函数:
函数声明void my function(int (^ square)(int));
调用这个函数l流程:
1、int (^square)(int) = ^(int){return a*a;};
2、myfunction(square);
当成objective-c method的传入值的话都是要把类型写在参数前面
-(void)objmethod:(int (^)int) square;
BLOCK的行为和特色:
在block里面存取外部变量的方法:
1、可以(读取)和块指针同一个作用域的变量
注意:是读取--------值传递;
2、直接存取static的变量
3、block变量
如果变量前面加上__block的话,这个变数称为block变量。(局部变量的static装饰)
生命周期
因为block也是继承自nsobject,所以其生命周期和记忆体的管理也就非常之重要。
block一开始都是被放到stack中,换句话说其生命周期随着method或function结束就会被收回。和一般变量一样。
关于记忆体的管理:
1、块指针的实体会在method或function结束后就被清理。
2、如果要保存block point的实体要用到copy指令,这样块指针就会被放到heap里。
2.1块主体里用到的块变量也会被搬到heap中。
2.2一般的variable值会被copy。
2.3如果主体里用到的变量是objective,会被retain,block被release时也会被release
2.4__
typedef int (^MyBlock)(int); MyBlock genBlock(); int main(){ MyBlock outBlock = genBlock(); int result = outBlock(5); NSLog(@"result is %d",[outBlock retainCount] ) ; // segmentation fault NSLog(@"result is %d",result ); return 0 ; } MyBlock genBlock() { int a = 3; MyBlock inBlock = ^(int n) { return n*a; }; return inBlock ; }此程式由genBlock里产生的block再指定给main function的 outBlock 变数,执行这个程式会得到
Segmentation fault
(注:有时候把genBlock里的a去掉就可以跑出结果的情形,这是系统cache住记忆体,并不是inBlock真得一直存在,久了还是会被回收,千万不要以为是对的写法)
表示我们用到了不该用的记忆体,在这个例子的情况下是在genBlock里的 inBlock 变数在return的时候就被回收了, outBlock 无法有一个合法的记忆体位置-retainCount就没意义了。
如果这个时候需要保留inBlock的值就要用-copy指令,将genBlock改成
MyBlock genBlock() {这样[inBlock copy]的回传值就会被放到heap,就可以一直使用(记得要release)
int a = 3;
MyBlock inBlock = ^(int n) {
return n*a;
};
return [inBlock copy ] ;
}
执行结果是
result is 1
result is 15 再次提醒要记得release outBlock。如果一回传[inBlock copy]的值就不再需要的时候可以这样写
MyBlock genBlock() {-copy指令是为了要把block从stack搬到heap,autorelease是为了平冲retainCount加到autorelease oop ,回传之后等到事件结束就清掉。接下来是block存取到的local variable是个物件的型别,然后做copy指令时
int a = 3;
MyBlock inBlock = ^(int n) {
return n*a;
};
return [[inBlock copy ] autorelease ] ;
}
MyBlock genBlock() {结果会印出
int a = 3;
NSMutableString * myString = [NSMutableString string];
MyBlock inBlock = ^(int n) {
NSLog(@"retain count of string %d",[myString retainCount]);
return n*a ;
};
return [inBlock copy] ;
}
retain count of string 2
这个结果和上面2.3提到的一样,local variable被retain了
那再来试试2.4,在local variable前面加上__block
MyBlock genBlock() {执行的结果就是会
int a = 3; __block NSMutableString * myString = [NSMutableString string]; MyBlock inBlock = ^(int n) { NSLog(@"retain count of string %d",[myString retainCount]); return n* a; }; return [inBlock copy] ; }
retain count of string 1
参考地址:http://fei263.blog.163.com/blog/static/9279372420113193523828/
AFNetworkong(参考地址:http://www.raywenderlich.com/zh-hans/36079/afnetworking速成教程(1)):
问题:一定是定义了nsdictionary为自定义键对象(参考地址:http://blog.csdn.net/yang3wei/article/details/7804171)
runloop的概念:http://blog.sina.com.cn/s/blog_7f7a975b0101arqi.html