美文网首页
OC语言day08-19copy和property

OC语言day08-19copy和property

作者: liyuhong165 | 来源:发表于2016-09-04 19:12 被阅读21次

pragma mark copy和property

pragma mark 概念

/**
 copy二个用途、一个引发问题
 
 1.copy的第一个用途, 防止外界修改内部的数据
 2.copy的第二个用途:__ 可以使用copy保存block, 这样可以保住 block中 使用的外界对象的命
 3.copy block之后引发 循环引用 (你引用我,我引用你 双方都无法释放)
 3.1 第三点出现的问题 需要对里面使用到的对象 添加一个 __block(意思是: 不要对block使用到该对象时, 进行一次retain操作)
 
 __block 用处
 1. 可以 在内部 修改 外部的值
 2. 并且引用计数不会加1
 
 */

pragma mark 代码

#import <Foundation/Foundation.h>
#pragma mark 类
#import "Person.h"
#import "Dog.h"
#pragma mark main函数
int main(int argc, const char * argv[])
{
#pragma copy和property
   
#pragma mark 一.copy的第一个用途, 防止外界修改内部的数据
 #warning 1.
    NSMutableString *temp = [NSMutableString stringWithFormat:@"lyh"];
    Person *p = [[Person alloc]init];
    p.name = temp;
    // 问题 : 修改了外面的变量, 影响到了 对象中的属性
    [temp appendString:@" cool"];
    NSLog(@"name = %@",p.name);
    // 记住 : 以后字符串属性都用copy
    NSLog(@"-----------1.end------------\n");

#warning 2.block 在内容修改 外部的值 (需要在 外部变量 添加 __block) [本质:block 默认存储在栈中 不会对外界的对象进行retain, 在堆才会]
    // 调用block 想在内部里面修改 外部的值 加上__block
    __block int num = 10;
    // 1. 定义block
    void (^myBlock) () = ^{
        num = 20;
        NSLog(@"%i",num);
        
    };
    
    // 2.调用block
    myBlock();
    // 3. block 默认存储在栈中, 栈中的block 访问到了外界的对象, 不会对 外界的对象的进行retain \
        block 如果在堆中, 如果 在block中访问了外界的对象, 会对外界的对象 进行一次retain
    NSLog(@"-----------2.end------------");

    
#warning 3.测试 将block 进行copy
    Person *p1 = [[Person alloc]init];
    NSLog(@"retainCount = %lu",[p retainCount]);
    // 1. 定义block
    void (^myBlock1) () = ^{
        num = 20;
        
        NSLog(@"%@",p);
        NSLog(@"retainCount = %lu",[p retainCount]);

    };
//    myBlock1();
    Block_copy(myBlock1); // 对block进行拷贝   // 将block转移到堆中
    myBlock1();
    NSLog(@"-----------3.end------------");

    
#pragma mark 二.copy的第二个用途:__ 可以使用copy保存block, 这样可以保住 block中 使用的外界对象的命
            // 避免以后调用 block的时候, 外界的对象 已经释放了
    
#warning 4.
    Dog *d = [[Dog alloc]init]; //  引用计算器 1
    NSLog(@"d tainCount = %lu",[d retainCount]);

    Person *p2 = [[Person alloc]init];
    p2.pBlock = ^{
        NSLog(@"%@",d); // 访问 这条狗
    };  // 对block进行赋值
    NSLog(@"d tainCount = %lu",[d retainCount]);    // 2

#warning 这里的block不知道什么时候调用 但是狗有可能提前释放了(开启僵尸对象 可以查看内存)
    // [Dog respondsToSelector:]
    // 如果狗仔 调用block之前释放了, 那么程序就会崩溃
    
    [d release]; // \
    [block 为assgin] 引用计算器 0 \
    [block 为copy 引用计算器 为 1]

    p2.pBlock(); // 执行p的block \
    [block 为assgin] 此处的狗的指针 是一个野指针 会崩溃 \
    [block 为copy 需要在dealloc里面进行[block 进行release] 操作  --- Block_release(_pBlock); ]
    [p2 release];
    NSLog(@"-----------4.end------------");

#pragma mark 三. copy block之后引发 循环引用 (你引用我,我引用你 双方都无法释放)
#warning 5.
    // 3. copy block之后引发 循环引用
    // 如果 对象中的block 有 用到了对象自己, 为了避免内存泄露, 应该将对象 修饰为 __block (里面不会进行retain了)
    __block Person *p3 =[[Person alloc]init];   // 1
    NSLog(@"p3 tainCount = %lu",[p3 retainCount]);
    p3.name = @"lyh";
    p3.pBlock = ^{
        NSLog(@"%@",p3.name);       // 2
    };
    NSLog(@"p3 tainCount = %lu",[p3 retainCount]);

    p3.pBlock();
    
    [p3 release];   // 1
//    [p3 release];   // 2B青年
    
    return 0;
}


Person.h //人类
#import <Foundation/Foundation.h>

typedef void (^myBlock)();

@interface Person : NSObject

//@property(nonatomic, retain)NSString *name;

@property(nonatomic, copy)NSString *name;

//  注意: 如果block 使用 copy 并不是 拷贝, 而是从栈区 转移到 堆区
@property (nonatomic,copy)myBlock pBlock;
@end
Person.m
#import "Person.h"

@implementation Person


- (void)dealloc
{
    // 只要 给 block 发送一条release消息, block中使用到的对象 也会收到该消息
    Block_release(_pBlock);
    NSLog(@"%s",__func__);
    [super dealloc];
}

@end

Dog.h //狗类
#import <Foundation/Foundation.h>

@interface Dog : NSObject

@end
Dog.m
#import "Dog.h"

@implementation Dog
- (void)dealloc
{
    NSLog(@"%s",__func__);
    [super dealloc];
}
@end

相关文章

  • OC语言day08-19copy和property

    pragma mark copy和property pragma mark 概念 pragma mark 代码 P...

  • iOS2023年最新面试题(持续更新中)

    OC和Swift语言基础 1、@synthesize和@dynamic分别有什么作用? @property有两个对...

  • iOS属性

    什么是属性 属性是OC语言中的一个机制,我们在OC中用@property来声明一个属性,其实@property是一...

  • OC语言@property @synthesize和id

    1.@property @synthesize关键字 *注意:这两个关键字是编译器特性,让xcode可以自动生成g...

  • OC语言@property@synthesize和id

    1.property @property是编译器的指令什么是编译器的指令,编译器指令就是用来告诉编译器要做什么 @...

  • 小谈@property的特质

    熟悉OC的小伙伴都会经常用到property(属性),属性是OC语言的一种特性,主要作用是封装对象中的数据,OC对...

  • iOS 成员变量、实例变量、property的区别和联系

    在iOS的第一个版本时,property是OC语言的一项新特性,在声明property之前必须首先声明与之对应的成...

  • OC @property

    @property(属性) 属性是对成员变量setter和getter的封装。 特性关键字 1. 原子性 atom...

  • OC - property

    @property变量 1.@property定义的变量,默认的修饰符是什么? 关于ARC下,不显示指定属性关键字...

  • OC -- @property

    建立一个Person类 @interface --> @end ==> .h中类的声明@implementatio...

网友评论

      本文标题:OC语言day08-19copy和property

      本文链接:https://www.haomeiwen.com/subject/wiglettx.html