weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环...

  • 同志们根据题目这些就是我平时 不太清楚的 我相信很多人也是不清楚的 所以我打算把他们弄明白了 为了给大家分享一下 自己做个笔记
  • weak 和strong的区别:
    weak:弱饮用。
    strong :强引用。
    我自己写了一个例子可以说明他们的区别:
@interface ViewController ()
@property (strong, nonatomic) myView *testView;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    myView *testView = [[myView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    testView.backgroundColor = [UIColor redColor];
    [self.view addSubview:testView];
    self.testView = testView;   
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"点击了界面了");
    [self.testView removeFromSuperview];
    NSLog(@"self.testView 的内存地址 %p",self.testView);
}
@end

#import "myView.h"

@implementation myView

-(void)dealloc{
    NSLog(@"已经被销毁了");
}

@end

然后打印的结果是:


weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第1张图片
1.png

可以看到 对象并没有销毁,下面用weak我们看一下的结果:


1.png

可以清楚的看到 对象销毁了,这说明强引用的对象在被移除的时候是没有完全移除的,内存地址中还保留着一块内存,只不过该内存地址指向的是空。
在举一个例子 ,我是引用别人的:
weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第2张图片
1.png

可以看到weak 在对象引用完毕就销毁了。他俩的区别暂时先说到这 ,后面的还有相应的介绍。

  • delagate 为什么用weak 那为什么不用strong呢?
    我们一般写delegate 这样写:


    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第3张图片
    1.png

    然后我们一般在调用她的地方是这样写的

self.delegate = self;

假如delegate 用strong修饰的话 那是不是就会导致循环引用了(self 强引用delegate ,delegate又指向了self),所以用weak了。

  • string为什么用copy?为什么很多时候不用strong呢?
    下面我用一个例子进行说明:


    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第4张图片
    1.png

    可以看到 用strong引用的话 会导致出现此类的问题
    如果我们换了copy:


    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第5张图片
    1.png

    可以看到 copy 解决了这个问题
    那么我们如果换成weak呢:
    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第6张图片
    1.png

    总结:copy主要是为了防止mutablecopy改变影响到自己,作用是为了安全。其实数组也是这个道理,但是数组我们经常用strong ,虽然mutablearray也是array的子类 但是我们很少会直接付值给他 所以也就不存在这种情况了,所以我们经常用strong在数组中 ,记住:string是可以用strong的 如果我们没有上述说的情况就可以。只不过我们为了安全性考虑用copy 更好些。

  • __block 我们在block中要改变外部某一个变量时,为什么必须的加上__block 才可以改 ,难道是因为语法吗?
    如果不加上__block的结果,可以看到我会报语法错误大致的意思是不能改,如果加上了__block就可以修改了,为什么呢?
    我们可以将我们的oc的代码转换成c++文件来看下,使用命令:
clang -rewrite-objc 源代码文件名   

看到的结果是:


weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第7张图片
image.png

可以看到一个局部变量加上__block之后 就会变成与block 一样的结构体,也就是报我们的成员变量拿到地址进行传递过去 ,这样的话block内部就能够修改了。

  • @dynamic 和 @synthesize
    @synthesize 是:告诉编辑器在编译的时候主动生成setter 和getter 方法,如果自定义了setter 和getter 方法那么将会覆盖。
    @dynamic:是告诉编辑器不生成setter 和getter 方法,由程序员自己手动创建。如果你没有创建setter 和getter 方法编译时候不会报错,在运行的时候会报错。如果这两一个一个都没有写 默认就是@synthesize var = _var;
    下面说一下俩的区别:


    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第8张图片
    image.png

    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第9张图片
    image.png

    可以看到他俩的区别
    其实@dynamic最常用的地方实在coredata中,编译的时候不用生成setter 和getter 方法在运行的时候开始调用 由coredata框架自动分配。

  • 深浅copy
    深copy:不但复制对象本身 还复制他的内存地址
    浅copy:只复制对象本身
    举一个例子:比如不可变的字符串 如果深拷贝的话 改变当前的字符串新生成的字符串的值也会改变,浅拷贝的话新生成的字符串的值不会改变。
    规律:1.本身对象是可变的 那么无论mutablecopy 还是copy 都是深拷贝。
    2.本身对象是不可变的 ,mutablecopy是深拷贝,copy是浅拷贝。
  • blcok的循环引用解释
    为什么会造成循环引用:block内部会对外部强引用调用block产生强引用(这句话不知道怎么说了,语文不好),block内部会对外部弱引用调用block产生弱引用。
    这就是造成循环引用的原因。
    举几个例子什么情况下会出现循环引用:


    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第10张图片
    image.png

    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第11张图片
    image.png

    image.png

    不调用deallloc方法
    这就是:block内部会对外部强引用调用block产生强引用
    如果我换成:weak


    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第12张图片
    image.png

    这就是:block内部会对外部弱引用调用block产生弱引用
    特殊著名的两种情况:
    1.block里边不能用下划线(_)给大家看一个结果
    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第13张图片
    image.png

    发现还是内存泄漏了,所以不能使用下划线
    还有一种情况:
    image.png

    这种是不会内存泄露的 因为我们self 没有强引用他
    给大家说一下 @strongify(self) 和单纯的weakSelf那个好
    @strongify(self):我没有倒入rac的那个框架,所以我给他说下为什么好


    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第14张图片
    image.png

    实际上 我们想要的结果是我们想三秒过后打印我们想要的结果,用weakself 是不行的 用@strongify 可以解决的
    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第15张图片
    image.png

    其实 rac中的@weakify 和 @strongify就是这个道理 。所以我们平时的那个weakself
  • delegate 和 通知的区别
    区别一 :delegate 有返回值,通知没有返回值 。
    区别二 :delegate 只能“单对单” 通知可以“一对多”,一个通知可以 发了 整个app可以同时接到通知 ,但是delegate就不行 在同一时刻只能完成一个响应的方法的实现。
    区别三:delegate 我们一般都是层级不是很深的情况使用,通知可以很深的层级(比如你可以从首页跳转到你app 很深的层级)。
  • new 和 alloc init的区别


    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第16张图片
    image.png

    可以看到 他们两个基本没有什么区别,alloc 把关联的对象分配到相邻的内存区域内,减少内存的消耗。而new的初始化方法只能是init,相对来讲alloc 更好一些。

  • block 使用
    1.blcok的语法,我在网上找个图片


    weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第17张图片
    image.png

    2.blcok作为属性使用

myView.h文件
#import 
@interface myView : UIView
@property (copy, nonatomic) void (^myBlock)(int x,int y);
@end
 myView.m文件
#import "myView.h"

@implementation myView
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if (self.myBlock) {
        self.myBlock(10, 10);
    }
}
@end
 ViewController.m文件
#import "ViewController.h"
#import "myView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    myView *obtainView = [[[NSBundle mainBundle]loadNibNamed:@"myView" owner:nil options:nil] lastObject];
    obtainView.frame = CGRectMake(0, 100, self.view.frame.size.width, 200);
    obtainView.myBlock = ^(int x, int y) {
        int sum = x + y;
        NSLog(@"�%d",sum);
    };
    [self.view addSubview:obtainView];
}

3.block 作为参数进行传递,最常见的是我们封装网络请求 或者写工具类的时候(这之前是我封装网络请求部分的代码)
例如:

        [weakSelf.manager POST:[weakSelf configUrl:weakSelf.requestUrl] parameters:weakSelf.paramDic constructingBodyWithBlock:^(id  _Nonnull formData) {
            [formData appendPartWithFileData:weakSelf.fileData name:weakSelf.name fileName:weakSelf.fileName mimeType:weakSelf.mimeType];
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            CGFloat progress = 1.0 * uploadProgress.completedUnitCount/uploadProgress.totalUnitCount;
            weakSelf.progress = progress;
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            [weakSelf detailSuccess:responseObject complete:complete];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [weakSelf detailError:error complete:complete];
        }];

4.blcok可以全局利用(个人理解),倒入头文件全局可以用
例如:

typedef void(^buttonBlock)(int a,int b);

@interface ViewController : UIViewController
@end

5.在方法中调用

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    buttonAction();
}
void (^buttonAction)() = ^{
    NSLog(@"大哥我开始在里边执行方法了");
};
weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环..._第18张图片
image.png

解释:这里为什么没写:if(buttonAction){buttonAction() };因为blcok我们确定是一定存在的 所以我们没有必要这样写,像1中如果不写if,那么我们在点击myview的时候就会crash。
6.作为函数的返回值(最常用的就是Masonry)作用就是:连式编程

- (MASConstraint * (^)(id attr))mas_equalTo;
- (MASConstraint * (^)(id))equalTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
    };
}
// 实现链式编程
[view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(superview.mas_top).with.offset(padding.top); //with is an optional semantic filler
    make.left.equalTo(superview.mas_left).with.offset(padding.left);
    make.bottom.equalTo(superview.mas_bottom).with.offset(-padding.bottom);
    make.right.equalTo(superview.mas_right).with.offset(-padding.right);
}];

-至此我们只是了解blcok的简单使用,更深层次的理解以及使用 我可能写不好了,我找了一篇文章 大家一起进步
block深入理解

你可能感兴趣的:(weak 、 strong、delegate为什么用weak、 copy、__block 、@dynamic与@synthesize、深浅copy、delegate 和通知区别、blcok的循环...)