实例变量 、 属性 、便利构造器、设置器、 访问器、实例方法("-") 、类方法("+"静态方法)、单例

类和对象
可以认为方法是面相过程的,而实例就是面相对象的。



实例变量

概述:
        实例变量又叫成员变量,它有三种访问修饰符@private,@protected,
@private,默认是@protected,在子类的实现文件中不能直接调用父类私有的变量(要用setter和getter方法才能访问到其父类私有的成员变量,这体现了面相对象的封装性);实例变量命名都用下划线“_”与系统命名保持一致
调用方式

@public 直接使用‘->’

@private @protected都需要分别给出设置方法和访问方法  

#import <Foundation/Foundation.h>

/*

 @abstrcut 学生实体类

 @author Elena

 */

@interface Student : NSObject

{

    int _age;    //实例变量

    NSString *_name;    //实例变量

}


属性
概述:

       属性可以认为是对象(或类)的特征,他表示了对象的当前状态,它是供外界访问和设置用的。
 
    property 属性是一组设置器和访问器,需要声明和实现,通过声明属性来摆脱繁琐的setter和getter方法,也就是说写了属性之后我们可以不必再写getter和setter方法了(它会通知编译器在内部就自动生成了setter和getter方法了,因此
它们在某种程度上是等价的,),但是属性自动生成的setter和getter方法只存在简单的赋值,没有逻辑判断。
    手动设置setter和getter方法的好处能进行正确性校验,业务逻辑判断。name = _name,_name是对外的也就是属性,name是对内的也就使成员变量。
    主张使用@property这样,这样不用在写setter和getter方法,
property中使用了retain那么在相应的dealloc方法中要将该成员变量release一次。特别注意:若属性是对象类型的那么必须使用retain

使用@property后系统生成的默认的setter方法 
示例代码

//默认的setter方法

-(void)setName:(NSString *)aName

{

    if (_name != aName)

    {

        [_name release];

        _name = [aName retain]; //这句话等价与 [aName rtain];   _name = aName;

    }

}

//默认的getter方法

-(NSString *)aName

{

    return _name;

}

 
属性的实现:

 
#import "Student.h"
            
@implementation Student

            @synthesize age = _age,name=_name;
            @end

便利构造器
便利构造器是一中特殊的方法,能快速的构造出一个对象并对其初始化。
这个初始化的临时对象不用手动释放,类方法的便利构造器初始化实例变量后不用手动release,然后直接用stu来调用类的方法来使用被初始化的值
 

//便利构造器

//示例方法

-(Student *)initWithName:(NSString *)name

                andAge:(int)age

              andHobby:(NSString *)hobby

            andAddress:(NSString *)address;

//类方法

+(Student *)studentWithName:(NSString *)name

                     andAge:(int)age

                    andHobby:(NSString *)hobby

                 andAddress:(NSString *)address; 



设置器setter
 格式:
set+首字母大写的实例变量名
声明部分(.h)

-(
void)setName:(NSString *)name;
-(NSString *)name; 
实现部分(.m)

-(void)setName:(NSString *)name

{

    self.name=name;

}

-(NSString *)name

{

    return _name;

}
 
访问器getter
与实例变量名相同(没有短横线),并且返回值类型也一致


方法
方法是类的行为,写在接口(.h)和实现(.m)两个文件中。在接口部分声明方法,在实现部分实现方法。
 

实例方法(“-”方法)
实例方法依赖于具体的对象,它必须通过对象来调用。
实例方法的调用
首先需要实例化该类         例如:Student *stu = [Student alloc] init];
[类的实例  实例方法名称]     例如:[stu sayHello];   
注意:此处实例化该类时,调用了该类的构造函数init,并且该类的构造函数调用[super init]的返回值不等于该类的self。
定义子类的实例
Woman *wife = [Woman alloc] init];
此处实例化该类时,调用了该类的构造函数init,并且该类的构造函数调用[super init]的返回值 等于该类的self。
 

类方法(“+”方法) 
类调用方法,不依赖于任何对象的方法,类似于c语言的static关键字 static函数。主要用于用在便利构造器和单例中
归纳小结 
 
类方法的调用  [类名称 类方法名称];
这里需要注意:
1、类方法可以调用类方法。
2、类方法不可以调用实例方法,但是类方法可以通过创建对象来访问实例方法。
3、类方法不可以使用实例变量。类方法可以使用self,因为self不是实例变量。
4、类方法作为消息,可以被发送到类或者对象里面去(实际上,就是可以通过类或者对象调用类方法的意思)。 

5、使用“+”方法,必须要初始化一个减号方法。
6、只在.m中实现,不在.h中声明,此时该方法或变量为私有的,不能被外部类所访问 ,此时在.m文件中会有一个警告。
7、调用方便。 

 

 
单例
单例模式(Singleton)主要用于做应用程序的资源共享控制。实质为,一个类里面只有一个对象,当强行创建多个对象,也只是对同一个对象起个别名而已,其实他们指向的都是同一个内存空间。
1)单例一定是类方法(“+”方法);
2)单例中的对象一定是static类;
3)单例中的对象初始化的时候赋值为空;
4)if(!对象名);
5)若对象不存在,则创建该对象;
6)最后返回改对象;
 
内存中的静态区
静态去中的变量是不需要释放的,静态变量只初始化一次
 
代码

+(id)getInstance

{

    static id teacher = nil;

    if (!teacher) {

        teacher = [[self alloc]init];

    }

    return teacher;

}

 

属性的属性

  属性也可以设置属性(attribute):读写(readonly,默认是readwrite)属性,原子性(atomic)属性,非原子性(nonatomic,这是不安全的)setter语义属性

(1)readonly 只读 ,也就是外部只能读取但是不能修改该属性

(2)给setter和getter方法起别名(setter = a:, getter = b)

       atomic  开启多线程变量保护,会消耗一定的资源(非原子性,保证多线程安全)

        nonatomic:禁止多线程变量保护,提高性能  

(3)setter语义属性:

assign:直接赋值,适用于基本数据类型(非对象类型)

retain:赋值时做内存优化,使用于对象类型

copy:复制一个副本,适用于特殊的对象类型(有NSCoping协议的才可以用copy)

assign retain copy的setter方法的内部实现(笔试题)

assign:

@property float price;

内部实现:

- (void)setPrice:(float)price 

 {

       _price = price;

}

getter是:

- (float)price

{

    return _price; 

retain:

@property (retain, readwrite, nonatomic) NSString *company;

内部实现:

- (void)setCompany:(NSString *)company{

      if(_company != company){

        [_company release];

        [company retain];

        _company = company; 

     } 

}

copy:

@property (copy, readwrite, nonatomic) NSString *company;

内部实现:

- (void) setCompany:(NSString *)company{

      if(_company != company){

           [_company release];

           [company copy];

           _company = company; 

      } 

三、使用属性和点语法

点语法(和[receriver message]是等价的)

1.性能有点差,内部转化为setter,getter

2.不易理解苹果的调用机制

3.属性

只要有setter(或getter)就可以使用点语法 

四、封装 

 封装的好处:

使用起来更加简单

变量更加安全

可以隐藏内部实现细节

开发速度加快 

致力于ios开发


http://item.taobao.com/item.htm?spm=a1z10.1.w5267445-2480627169.23.dbJJxG&id=20257771217

另外,总结一下:

1.       静态变量位于方法区,生命周期取决于类何时被加载及卸载。

2.       实例变量位于堆区,生命周期取决于实例何时被创建及销毁。

3.       局部变量位于栈区,生命周期取决于所属的方法合适被调用及结束调用。


1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 
4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。

原文地址:https://www.cnblogs.com/yuanyuandachao/p/3728480.html