码迷,mamicode.com
首页 > 其他好文 > 详细

实例变量和属性

时间:2014-12-17 14:46:09      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:des   style   ar   io   os   使用   sp   for   on   

概要

       在开发IOS中,发现自己对属性和实例变量存在一定的困惑,所以今天花了时间查资料以及做实验,顺便记录一下自己的体会。

       属性和实例变量都是类的对象实例所有,属性是方法,可使用点(.)调用也可以按照OC的正常方法调用,对于一般的属性赋值其实就是调用属性的设置方法;实例变量如果可以访问,需要使用指针访问形式(当然因为访问的实例是一个指针)。正常情况下,属性和实例变量没有直接的关联,但是通过@synthesize指定以及LLVM的名字规则可以把实例变量和属性关联起来。

       可以使用@synthesize直接给属性指定其对应的实例变量(@synthesize per =_author; 实例变量_author和属性per关联上了,和名字无关),如果没有指定,但是符合LLVM的命名规范,也可以把实例变量和属性关联起来。实际上,LLVM会将属性per和成员变量_per关联起来,而且如果没有_per实例变量定义,LLVM会自动合成该私有的实例变量,供类正常使用。


结果展示

2014-12-17 11:07:03.208 MemberProperty[43430:2367258] 
name : Book.
author : Author.
publisher : Publisher.
align name : NameAlign.
2014-12-17 11:07:03.209 MemberProperty[43430:2367258] 
name : main_set_name
author : main_set_author
publisher : main_set_publisher
align name : ok?
2014-12-17 11:07:03.209 MemberProperty[43430:2367258] 
name : set_name
author : setsetAuthor
publisher : setPublisher
align name : setNameAlign

流程概要

    定义一个类校验各种猜想


主要代码

h文件

//
//  Book.h
//  MemberProperty
//
//  Created by arbboter on 14/12/17.
//  Copyright (c) 2014年 arbboter. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Book : NSObject
{
    // 默认protect成员变量
    NSString* _name;
    NSString* _author;
    
@public
    NSString* _nameAlign;
    
@private
    NSString* _nameIn;
    
@protected
    NSString* _protectName;
}

/* 属性声明 头文件中的public.protect.private成员变量都可以指定为属性 */

// 声明属性_name,由m文件对应的synthesize自动合成_name和set_name方法(合称属性方法)
// (不建议使用)
@property (nonatomic, retain) NSString* _name;

// 声明属性,使用LLVM自动添加该属性的合成方法(因为m文件没有@synthesize指定该属性)
// 该属性自动和成员变量_nameAlign关联
@property (nonatomic, retain) NSString* nameAlign;

// 声明属性,自动合成属性方法,m文件中使用synthesize指定和成员变量_author关联
// (以前比较规范额使用方法,现在可以直接利用LLVM省去,详见publisher的使用)
@property (nonatomic, retain) NSString* author;

// 声明属性,由LLVM自动生成成员变量_publisher和属性方法,合成的成员变量是private类型
// (私有变量推荐使用这种方法)
@property (nonatomic, retain) NSString* publisher;

// 声明属性,由LLVM自动合成属性方法,并且由LLVM指定其和成员变量_nameIn关联
// (私有成员变量不建议使用,因为会自动合成私有的成员变量,所以可以去掉成员变量的声明)
@property (nonatomic, retain) NSString* nameIn;

// 声明属性,由LLVM自动合成属性方法,并且由LLVM指定其和保护成员变量_protectName关联
// (保护变量使用这种类型声明)
@property (nonatomic, retain) NSString* protectName;

@end

/* 总结:实例变量和属性的关系
 * 最新的编译器的LLVM支持自动给属性(eg.myproperty)合成属性方法并关联实例变量(_myproperty),如果该实例变量存在,直接关联。
 * 如果该实例变量不存在,则自动给类添加该实例变量,该实例变量是私有类型(private)。这样的话,只需要在头文件使用@property声
 * 明一个属性,我们就可以正常使用该属性,而且在类里面能直接使用对应的私有变量。如果你想修改自动合成的_myproperty访问类型,需要
 * 在类的头文件定义所需的访问类型的实例变量。当然,以前的用_var定义变量然后使用synthesize指定var=_var的方法也值得推荐的,不过相对上述方法而言,我还是喜欢现在说的这种。
 */


m文件

//
//  Book.m
//  MemberProperty
//
//  Created by arbboter on 14/12/17.
//  Copyright (c) 2014年 arbboter. All rights reserved.
//

#import "Book.h"

@implementation Book
{
    // 声明有一个私有变量,不能使用指定为属性
    NSString* _no;
}

@synthesize _name;
@synthesize author = _author;

- (NSString*)description
{
    NSString* str = [NSString stringWithFormat:@"\nname : %@\nauthor : %@\npublisher : %@\nalign name : %@\n",
                     _name, _author, _publisher, _nameAlign];
    return str;
}

- (id)init
{
    self = [super init];
    if(self)
    {
        _name = [[NSString alloc] initWithString:@"Book."];
        _author = [[NSString alloc] initWithString:@"Author."];
        _publisher = [[NSString alloc] initWithString:@"Publisher."];
        _nameAlign = [[NSString alloc] initWithString:@"NameAlign."];
    }
    return self;
}

- (void)dealloc
{
    [_name release];
    [_author release];
    [_publisher release];
    [_nameAlign release];
    [super dealloc];
}
@end

main文件

//
//  main.m
//  MemberProperty
//
//  Created by arbboter on 14/12/17.
//  Copyright (c) 2014年 arbboter. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Book.h"
int main(int argc, const char * argv[])
{
    Book* b = [[Book alloc] init];
    
    NSLog(@"%@", [b description]);
    
    /*
     * 点语法的本质是方法的调用,而不是访问实例变量,当使用点语法时,编译器会自动展开成相应的方法。
     * 点语法的本质是转换成相应的set和get方法,如果没有set和get方法,则不能使用点语法。
     */
    
    // 直接赋值型 实际上调用的还是set方法 (隐式调用set方法)
    b._name = @"main_set_name";
    b.author = @"main_set_author";
    b.publisher = @"main_set_publisher";
    b.nameIn = @"private member set ok?";
    b.nameAlign = @"main_set_align_name";
    // _nameAlign是pulich实例变量,所以可直接访问变量赋值
    b->_nameAlign = @"ok?";
    NSLog(@"%@", [b description]);
    
    // 显示调用set方法
    [b setAuthor:@"setsetAuthor"];
    [b setPublisher:@"setPublisher"];
    [b set_name:@"set_name"];
    [b setNameAlign:@"setNameAlign"];
    NSLog(@"%@", [b description]);
    
    // 错误用法
    /* 默认私有变量不能访问 */
    // b->_author;
    
    [b release];
    return 0;
}

项目工程

实例变量和属性

标签:des   style   ar   io   os   使用   sp   for   on   

原文地址:http://blog.csdn.net/arbboter/article/details/41979767

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!