zoukankan      html  css  js  c++  java
  • iOS 52个技巧学习心得笔记 第二章 对象 , 消息, 运行期

    1. 属性

    在开发过程中经常要用到定义属性,@property和@synthesize是经常用到的属性, property在.h文件中作声明,@synthesize在.m文件中用于实现
    //  Student.h
    //  property
    //
    //  Created by Rio.King on 13-8-25.
    //  Copyright (c) 2013年 Rio.King. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    @interface Student : NSObject
    {
        int age;
        int no;
    }
    
    //当编译器遇到@property时,会自动展开成getter和setter的声明
    @property int age;
    @property int no;
    
    
    @end
    
    
    Student.m
    
    //
    //  Student.m
    //  property
    //
    //  Created by Rio.King on 13-8-25.
    //  Copyright (c) 2013年 Rio.King. All rights reserved.
    //
    
    #import "Student.h"
    
    @implementation Student
    
    //@synthesize 会自动生成getter和setter的实现
    //@synthesize 默认会去访问age,no,height同名的变量,,
    //如果找不到同名的变量,会在内部自动生成一个私有同名变量age,no,height,,
    //因此Student.h 中的这几个变量也可以省略不写。
    @synthesize age,no;
    
    @end
    说明:在xcode4.5以后 可以省略@synthesize ,编译器会自动帮你加上getter 和 setter 方法的实现,并且默认会去访问_age这个成员变量,如果找不到_age这个成员变量,会自动生成一个叫做 _age的私有成员变量.
     而我在实际开发使用上的经验是 尽量使用”点语法”,可读性更强.涉及setter  getter  初始化时候我才会使用_age.
    例如:
    
    
    
#pragma mark - getter and setter
    //当有实例方法中调用 “self.titleLab”就会自动调用以下 setter getter 方法 (UILabel *)titleLab
    {
        if(!_titleLab){
            UILabel * titleLab = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, self.view.width, HF_BUTTON_HOME_TEST_HEIGHT)];
            titleLab.textAlignment = NSTextAlignmentCenter ;
            titleLab.text = @"选择生日";
            titleLab.font = HF_TITLE_BOLD_FONT ;
            [self.view addSubview:titleLab];
            _titleLab = titleLab;
        }
        return _titleLab;
    }
    2, 认识几个关键字
    (1)atomic:原子操作(线程安全) (原子性 是指事物的一个完整操作,操作成功就提交,反之就回滚.原子操作 指的是具有原子性的操作)
    
    OC属性设置里面默认是atomic 原子属性,意思是 setter/getter函数就是一个原子操作,如果多线程操作 setter 那么 相当于 在函数头尾加了锁 防止资源竞争造成的死锁.(不会出现某一个线程执行完setter所有语句之前,另一个线程就开始执行setter)
    (2)nonatomic:非原子操作(线程不安全) 一般不需要多线程支持的时候 就用 nonatomic.这样并发访问的效率就会比较高.如果 一个属性要在多线程中使用,那么 就该用原子属性的atomic.
    
    但是 在开发iOS程序时应该使用nonatomic属性,因为atomic属性会严重影响性能, 我们一般在使用nonatomic过程中加锁之类的方法做到数据同步.
    通常说nonatomic 是提高在非多线程应用中的读写效率
    
    如果问 这俩谁是线程安全的,原子性安全 所以是atomic更安全 
    
    @property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@syntheszie var = _var;
    区别 使用@synthesize,编译器会确实的产生getter和setter方法,而@dynamic仅仅是告诉编译器这两个方法在运行期会有的,无需产生警告。
    
    (3)synthesize  会自动生成getter和setter的实现 如果不实现setter和getter方法,编译器将会自动在生产setter和getter方法
    (4) dynamic  就是要来告诉编译器,代码中用@dynamic修饰的属性,其getter和setter方法会在程序运行的时候或者用其他方式动态绑定,以便让编译器通过编译。其主要的作用就是用在NSManageObject对象的属性声明上,由于此类对象的属性一般是从Core Data的属性中生成的,Core Data框架会在程序运行的时候为此类属性生成getter和Setter方法。
         假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var =someVar,由于缺setter方法会导致程序崩溃;或者当运行到 someVar = var时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。这个 时候 自己要写实例方法 进行getter  读取 或者 setter 进行赋值(注意防止方法自己调用自己 造成死循环)
    
    正确使用举例:
    
    #pragma mark - getter and setter
    
    - (UILabel *)noteLabel
    {
        if (!_noteLabel) {//_noteLabel在这里是私有创建, 在@dynamic 里不会自己生成
            UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 64.0 + 22.0, SCREEN_WIDTH - 100, 40.0)];
            [label setTextAlignment:NSTextAlignmentCenter];
            [label setFont:[UIFont boldSystemFontOfSize:16.0]];
            [label setTextColor:[UIColor grayColor]];
            [label setText:self.noteText];
            [label setNumberOfLines:0];
            [label setLineBreakMode:NSLineBreakByWordWrapping];
            
            _noteLabel = label;
        }
        return _noteLabel;
    }
    
    (4)assign : 简单赋值操作,不更改索引计数
    对基本数据类型 (例如NSInteger,CGFloat)和C数据类型(int, float, double, char, 等)       适用简单数据类型
    (5)strong :我习惯叫它”强引用(apple说是strong reference)”(书上管它叫 拥有关系(owning relationship)) 当前对象被其他对象引用时,会执行retain操作,引用计数器+1。当retainCount=0时,该对象才会被销毁。因为我们要进行对象的内存管理,所以这是默认的引用方式。(默认是强引用)
               一个对象只有在它的所有强引用都被释放后才能被回收.
    (6)weak   :”弱引用”(非拥有关系 nonowning relationship) 当它的生存周期到了时就会被销毁,弱引用在可能会出现循环引用的情况下是必不可少的. 
    
    strong VS weak
    强引用持有对象  弱引用 不持有  当弱引用指向一个强引用所持有的对象时,当强引用赋值为nil 弱引用自动被赋值nil
    如果弱引用被赋值为nil  强引用依旧持有原来的对象
    
    
    strong,weak, unsafe_unretained往往都是用来声明属性的如果想声明临时变量就得用__strong,  __weak, __unsafe_unretained,  __autoreleasing, 其用法与上面介绍的类似。
    
    
    (7)retain :手动释放内存时候使用,相当于ARC中的strong 
    
    (8)copy :(浅拷贝,指针拷贝)a 和 b 指向同一个对象  共用同一块内存
    (9)mutable:(深拷贝,内容拷贝) 做”影子数据”时候使用 是完全新的一个对象
    
    举例:1
          NSString *string = @"origion";
          NSString *stringCopy = [string copy];
          NSMutableString *stringMCopy = [string mutableCopy];
          
          [stringMCopy appendString:@"!!"];
         //内存
         NSLog(@"
     string:%p 
     stringCopy:%p 
    stringMCopy:%p 
    ",string,stringCopy,stringMCopy);
         //对象
         NSLog(@"
     string:%@
    stringCopy:%@
    stringMCopy:%@
    ”,string,stringCopy,stringMCopy);
    
        2016-02-16 17:35:04.284 dailylife[1665:183019]
        string:0x10d58a4d0
        stringCopy:0x10d58a4d0 //copy -> 和string 共用同一块内存地址 (同一个指针)
        stringMCopy:0x7f92e47375d0 //multableCopy 新的一块内存指针
        2016-02-16 17:35:21.479 dailylife[1665:183019]
        string:origion
        stringCopy:origion // copy -> 同一个对象
        stringMCopy:origion!! //multableCopy 一个新对象
    举例2
    NSMutableString *string = [NSMutableString stringWithString: @"origion"];
         NSString *stringCopy = [string copy];
         NSMutableString *mStringCopy = [string copy];
         NSMutableString *stringMCopy = [string mutableCopy];
    
         //[mStringCopy appendString:@“mm"];//error 可变字符串应该使用”可变拷贝”multableCopy 才可使用 这类方法
         [string appendString:@" origion!"];
         [stringMCopy appendString:@"!!"];
         
        //内存
        NSLog(@"
     string:%p 
     stringCopy:%p 
     mStringCopy :%p
    stringMCopy:%p 
    ",string,stringCopy,mStringCopy,stringMCopy);
        //对象
        NSLog(@"
     string:%@
    stringCopy:%@
    mStringCopy:%@
    stringMCopy:%@
    ”,string,stringCopy,mStringCopy,stringMCopy);
       
    2016-02-16 17:54:46.019 dailylife[2039:201349]
    string:0x7ff993f71800
    stringCopy:0x7ff993f71860
    mStringCopy :0x7ff993f71880
    stringMCopy:0x7ff993f718a0   //四个不同对象不同指针
        
    2016-02-16 17:54:48.107 dailylife[2039:201349]
    string:origion origion!
    stringCopy:origion
    mStringCopy:origion
    stringMCopy:origion!!        //四个不同对象不同指针
  • 相关阅读:
    Do I Have an RNG(Random Number Generator)?
    网页上判断屏幕分辨率
    〖005〗数据监控
    How to use Emerge
    〖006〗开发语言
    Build patched kernel
    GNAP 1.5.1
    五一长假日记(1)
    SQL Server各种日期计算方法
    HOWTO Design your own Framebuffer Splash
  • 原文地址:https://www.cnblogs.com/someonelikeyou/p/5201694.html
Copyright © 2011-2022 走看看