标签:
(1)block
- (void)viewDidLoad {
    [super viewDidLoad];
    __block int a=10;
    NSLog(@"a=%d",a);
    void (^blockName)()=^{
        a=20;
    };
    NSLog(@"a=%d",a);
    blockName();
    NSLog(@"a=%d",a);
}——只要在变量前面增加__block,在block里面就可以修改该变量的值。当然也有其他方法如添加static等。
——如何能实现,需要查看底层代码,也就是用C语言写成的运行时代码。在终端利用clang -rewrite-objc .m文件名,把文件转为.cpp的C++底层代码,可以分析底层实现的原理,可以用open .cpp文件名,打开查看。
——核心原理是,因为有一个__forwarding参数,每次输出都是调用a.__forwarding->a的值。而且block本质上就是一个指向结构体的地址。
(2)运行时,平时我们写得代码其实最终都会转成运行时代码,效率快。但是我们一般用OC写。如果非要使用运行时代码方式书写,可以增加下面的类。
#import <objc/message.h>//需要用到发送消息的时候,设置函数的时候 #import <objc/runtime.h>//里面有一些特殊的函数
——使用价值之一。我们平时的分类一般只能扩充一个类的方法,而不能扩充它的成员属性。而使用的某些方法(如下)就可以为类动态地扩充成员属性。
static double heightKey;
-(void)setHeight:(double)height{
    objc_setAssociatedObject(self, &heightKey, @(height), OBJC_ASSOCIATION_ASSIGN);
}
-(double)height{
    return [objc_getAssociatedObject(self, &heightKey) doubleValue];
}#import "ViewController.h"
#import "Person.h"
#import <objc/message.h>
#import <objc/runtime.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    unsigned int count=0;
    //可以获得类的所有成员属性,默认指向0,即类的第一个成员属性
    Ivar *ivars=class_copyIvarList([Person class], &count);
    //遍历成员变量
    for (int i=0; i<count; i++) {
        Ivar ivar=ivars[i];
        const char *name=ivar_getName(ivar);
        const char *type=ivar_getTypeEncoding(ivar);
        NSLog(@"%s,%s",name,type);
    }
}_age,i _name,@"NSString"
——默认情况下,block是存档在栈中,可能被随时回收,需要copy操作。这也就是我们在定义block的时候用得时copy。而不是weak等等。
//默认是放在栈中,可能会被随时销毁
    void (^blockName)()=^{
        
    };
    //进行一次copy操作,就可以放在堆中了。
    //[blockName copy];
    //以下方法也一样。但是只能在非ARC中使用。
    //Block_copy(blockName);
    
    //用retain没有用的原因:retain只是增加一次计数,block内存还是在栈中,并没有转移到堆中。    Person *person=[[Person alloc]init];
    person.blockName=^{
        person.age=20;
    };    Person *person=[[Person alloc]init];
    __unsafe_unretained Person *person0=person;
    person.blockName=^{
        person0.age=20;
    };
【iOS开发-117】block为什么用copy?利用runtime运行时的objc_方法为分类扩充成员变量
标签:
原文地址:http://blog.csdn.net/weisubao/article/details/43307699