苹果官方文档学习 ----arc 对象所有权

  **对象的属性


    对象的属性封装了对象的所有值
   所有的对象为了执行特定任务都需要记录信息,
   1、许多对象被设计是为了模仿一个或者多个值,比如NSNumber类把数值型数据转换成啦数值对象;XYZPerson类模仿人拥有firstName和lastName;
   2、有些对象在关系记录上应用较多,假定一个对象关联用户界面和界面所展示的信息,甚至对象需要记录用户界面元素和与界面关联的信息;

  **申明暴露在外面的公共数据属性

    1、不希望用户通过set方法修改属性
     @property (readonly) NSString *fullName;

 **通过对象的所有权管理对象的生命周期

     1、copy  跟MRC一样
          + 在ARC中,系统不会自动加入copy,申请所有权,需要手动添加
             实例:
- (id)initWithSomeOriginalString:(NSString *)aString {
    self = [super init];
    if (self) {
        // 如不添加copy,系统自动添加strong,一旦外部string指向的对象改变,_instanceVariableForCopyProperty指向的对象也将改变
        _instanceVariableForCopyProperty = [aString copy];
    }
    return self;
}
     +copy基础
    /*
       copy
     官方解释:
     The copy attribute means that the property will use a strong reference, because it must hold on to the new object it creates.
     如果之前习惯使用MMC的伙伴,那么在使用arc之后,对于NSString对象,仍然用copy申请所有权,
     虽然arc可以使用strong,但使用strong,对象值改变,所有指针的值,都会改变
     */
    //当first引用 strong 索取所有权时
    self.badageView = [[XYZBadageView alloc] init];
    NSMutableString *nameString31 = [NSMutableString stringWithString:@"John"];
    NSLog(@"self.badageView%@,nameString%@",self.badageView.firstName,nameString);
    self.badageView.firstName = nameString31;
    [nameString31 appendString:@"ny"];
    NSLog(@"self.badageView%@,nameString%@",self.badageView.firstName,nameString);
    //    2014-02-21 16:27:26.345 ARCTest[4394:a0b] self.badageView(null),nameStringJohn
    //    2014-02-21 16:27:26.346 ARCTest[4394:a0b] self.badageViewJohnny,nameStringJohnny


    //当first引用 copy 索取所有权时
    self.badageView = [[XYZBadageView alloc] init];
    NSMutableString *nameString32 = [NSMutableString stringWithString:@"John"];
    NSLog(@"self.badageView%@,nameString%@",self.badageView.firstName,nameString);
    self.badageView.firstName = nameString32;
    [nameString32 appendString:@"ny"];
    NSLog(@"self.badageView%@,nameString%@",self.badageView.firstName,nameString);
//    2014-02-21 16:55:18.197 ARCTest[4606:a0b] self.badageView(null),nameStringJohnny
//    2014-02-21 16:55:19.659 ARCTest[4606:a0b] self.badageViewJohn,nameStringJohnny

      note :block使用copy申请所有权
    2、strong
        strong同之前retain,增加引用计数;
        需要注意一下几点
    /*
       加号方法创建的对象释放不及时
     */
    self.lastModificationDate = [[NSDate alloc] initWithTimeIntervalSince1970:200];
    NSDate *__weak originalDate11 = self.lastModificationDate;
    self.lastModificationDate = [NSDate date];
    NSLog(@"Last modification date changed from %@ to %@",
          originalDate11, self.lastModificationDate);
    //   Last modification date changed from (null) to 2014-02-21 08:46:58 +0000
    
    self.lastModificationDate = [NSDate dateWithTimeIntervalSince1970:200];
    NSDate *__weak originalDate12 = self.lastModificationDate;
    self.lastModificationDate = [NSDate date];
    NSLog(@"Last modification date changed from %@ to %@",
          originalDate12, self.lastModificationDate);
    
   //    Last modification date changed from 1970-01-01 00:03:20 +0000 to 2014-02-21 08:47:08 +0000
     
    /*
     强引用会因为对象的改变而改变,不会因为之前指针的转变而转变
     */
    
    self.lastModificationDate = [[NSDate alloc] initWithTimeIntervalSince1970:200];
    NSDate *originalDate = self.lastModificationDate;
    self.lastModificationDate = [NSDate date];
    NSLog(@"Last modification date changed from %@ to %@",
          originalDate, self.lastModificationDate);
//    Last modification date changed from 1970-01-01 00:03:20 +0000 to 2014-02-21 08:43:58 +0000
    
    self.badageView = [[XYZBadageView alloc] init];
    NSMutableString *nameString = [NSMutableString stringWithString:@"John"];
    NSLog(@"self.badageView%@,nameString%@",self.badageView.firstName,nameString);
    self.badageView.firstName = nameString;
    [nameString appendString:@"ny"];
    NSLog(@"self.badageView%@,nameString%@",self.badageView.firstName,nameString);

      + 循环引用
         循环引用示意图
         
     避免循环引用示意图
           
+
        见下表: 

      @property (weak) id delegate;

      @property (weak) id delegate;

       note:weak的反义词是strong,此处没有必要特意申明,因为他是默认的

+      

    本地变量、成员变量默认申请强引用所有权(不在是autorelease)

   

self.lastModificationDate = [[NSDate alloc] initWithTimeIntervalSince1970:200];
    NSDate *originalDate = self.lastModificationDate;
    self.lastModificationDate = [NSDate date];
    NSLog(@"Last modification date changed from %@ to %@",
          originalDate, self.lastModificationDate);
    //Last modification date changed from 1970-01-01 00:03:20 +0000 to 2014-02-21 10:15:50 +0000

Note:变量的强引用范围仅限于所在的方法作用域内,除非他指向啦其他的对象,或者被置空啦

如果你不想强引用本地变量的话,使用__weak:

NSObject * __weak weakVariable;

因为weak不申请对象的所有权,对象正在使用的时候被销毁是可以的。要避免这种危险的操作,当对象被释放之后,弱引用指针将会自动置空

self.lastModificationDate = [[NSDate alloc] initWithTimeIntervalSince1970:200];
    NSDate *__weak originalDate = self.lastModificationDate;
    self.lastModificationDate = [NSDate date];
    NSLog(@"Last modification date changed from %@ to %@",
          originalDate, self.lastModificationDate);
    //2014-02-21 18:31:44.837 ARCTest[4875:a0b] Last modification date changed from (null) to 2014-02-21 10:31:44 +0000

originalDate变量很有可能被置空,当self.lastModificationDate 指针的指向改变,他对之前对象的强引用将消失,如果对象没有其他的对象指向他,对象将会被销毁,originalDate 将被置空

弱引用是令人很烦恼的,尤其下面这样:

NSObject * __weak someObject = [[NSObject alloc] init];
+ 下面这种写法是不安全的在上述代码中,新创建的对象没有被强引用,所以对象将会立即销毁,someObject指针将被置空

if (self.someWeakProperty) {
 [someObject doSomethingImportantWith:self.someWeakProperty];
     [someObject doSomethingImportantWith:self.someWeakProperty];
}

因为在多线程应用中,someWeakProperty指向的对象可能会被释放,if判断做得安全监测是无效的,你可以采用下面的方法(这个不太理解,在多线程中,下面的方法,同样不安全~~~)

  

  NSObject *cachedObject = self.someWeakProperty;           // 1
if (cachedObject) {                                       // 2
   [someObject doSomethingImportantWith:cachedObject];   // 
  [someObject doSomethingImportantWith:cachedObject];   // 3
  }                                                         // 4
  cachedObject = nil;   

Use Unsafe Unretained References for Some Classes
 Cocoa and Cocoa Touch 框架中,有些类是不支持弱引用的;比如: NSTextView、NSFont、NSColorSpace;
上述类中,如果你想引用中任意一个类,需使用theunsafe_unretained;
@property (unsafe_unretained) NSObject *unsafeProperty;

 NSObject *  NSObject * __unsafe_unretained unsafeReference;
unsaft引用和weak都有不保留对象所有权的性质,但是如果对象释放啦,他不会把对象置空

本文翻译来源:




          
       代码实践,分线程要加自动释放池。队列的子类main方法,添加自动释放池,防止内存泄露
        
              



   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值