ios开发的objective-c中hm文件中interface|iOS开发的Objective-C中.h、.m文件中@interface、@synthesize讲解

更新时间:2019-12-07    来源:ios    手机版     字体:

【www.bbyears.com--ios】

一般的,写一个Class的时候,经常是这种格式(以UIViewController为例):

.h文件:

@interface ClassName{
    NSString* _value1;
}
@property(nonatomic,assign)NSString* value1;
-(void)func1;


.m文件:

@interface ClassName(){
}
@end
@synthesize value1;
@implementation ClassName
-(void)func1{
}
@end


大体上就是这个格式。很多人,包括我,在创建和使用Class时,直接就使用这样的模板。这个模板里有一些有意思的小东西,值得探讨,比如:
1. 为什么.h文件和.m文件里各有1个@interface?它们分别有什么用?
2. .h中,value1为什么要定义2遍?
3. @synthesize有什么用?
还有一些其它的问题,今天先解决上面提到的这几个。
为什么.h文件和.m文件里各有1个@interface?它们分别有什么用?

.h里面的@interface,不消说,是典型的头文件,它是供其它Class调用的。它的@property和functions,都能够被其它Class“看到”。

而.m里面的@interface,在OC里叫作Class Extension,是.h文件中@interface的补充。但是.m文件里的@interface,对外是不开放的,只在.m文件里可见。

因此,我们将对外开放的方法、变量放到.h文件中,而将不想要对外开放的变量放到.m文件中(.m文件的方法可以不声明,直接用)。

有的同学看到Class Extension,可能会想到OC里的@protocol。是的,它们都是对一个Class的扩展。不过它们的区别也很明显:

Class Extension只能用在能得到源代码的情况下,而@protocol在得不到源码的时候也可以使用。

因此@protocol一般用作对一些系统Class的扩展,常见的比如对NSString、UIView等。
.h中,value1为什么要定义2遍?

当然,现在@interface{}里的定义也可以省略掉了,不过原理还是要搞清楚。

严格来说@interface{}里定义的变量,叫作instance variable,它是这个Class内部真正的全局变量。然而这个instance variable是不对外公开的,因此我们还需要一个对外公开的东西来调用,就是@property
@property是对外的,它其实是告诉大家,我这个Class里,有一个变量的set/get方法。比如,@property NSString* string; 就是说,本Class里有一个getString/setString供你们调用。

因此需要2次声明。当然现在lldb也升级了,只要你声明了@property,它就可以自动创建对应的全局变量。
@synthesize有什么用?

@property 一个变量后,在@implementation里再@synthesize一下,相信是很多人的习惯。但是为什么要有这个@synthesize方法呢?

@property是对外声明了Class的get/set方法,然后我们就需要在.m文件里手写get/set方法。这可就麻烦了,1个变量对应2个方法,假如一个Class里有10个变量,那岂不是要写20个方法?烦也烦死唠。

@synthesize帮我们解决了这个问题。@synthesize在.m文件里自动生成了get/set方法。因此,我们只要在@implementation后面加上一行:@synthesize 就可以自动生成get/set方法了,省掉了很多麻烦。比如@synthesize value1 = _value1;的意思就是,将instance variable _value1用作getValue1和setValue1方法里。

get/set方法有时候是比较复杂的,因为它和变量的属性相关,就是@property(nonatomic, assign/retain(strong/weak))这就和内存有关了。然而@synthesize为我们做了这些事情,就不要再为这些事情烦恼了!

更方便的是,从Xcode4.4开始,编译器会自动为每一条@property都添加一条对应的@synthesize,因此以后我们只要写一个@property就可以了!

PS:这些在Swift貌似都不是个事儿了。话说到现在都没怎么接触过Swift,真是罪过罪过。



Objective-C中的@property,@synthesize和点语法

1.普通的设置器和访问器

Person.h

    #import   
      
    @interface Person : NSObject{  
        int identify;  
        int age;  
    }  
      
    - (void)setIdentify:(int) identify;  //设置器  
    - (int)identify;                     //访问器  
    - (void)printInfo;  
    @end


Person.m

    #import "Person.h"  
      
    @implementation Person  
      
    - (void)setIdentify:(int) _identify{  //设置器  
        identify = _identify;  
    }  
    - (int)identify{                      //访问器  
      
        return identify;  
    }  
    - (void)printInfo{                    //打印identify  
        NSLog(@"Person identify is: %d",identify);  
    }  
    @end


Main.m
   

#import   
    #import "Person.h"  
      
    int main(int argc, const char * argv[])  
    {  
      
        @autoreleasepool {  
              
            // insert code here...  
            NSLog(@"Hello, World!");  
            Person *person = [[Person alloc] init];  
            [person setIdentify:100];  
            NSLog(@"Person identify: %d",[person identify]);  
              
        }  
        return 0;  
    }



2. 使用@property和@synthesize来简化设置器和访问器

Person.h
   

#import   
      
    @interface Person : NSObject{  
        int identify;  
        int age;  
    }  
      
    @property(nonatomic) int identify;  
    @end


Person.m
   

#import "Person.h"  
      
    @implementation Person  
    @synthesize identify = _identify;  
    @end



在@property()括号中,可以填写的属性有:

    readwrite:默认,便是属性是可读写的,也就是说可以使用getter和setter
    readonly: 只读,意味着没有set方法,只能使用getter
    assign:    默认,引用计数不增加
    retain:      引用计数增加1
    原子性:    actomic 默认
    非原子性:nonatomic,表示不用考虑线程安全问题

    assign(缺省),retain,copy是属性如何存储;
    atomic是oc中的一种线程保护技术,是防止在未完成的时候,被另外一个线程使用,造成数据错误;
    @synthesize是合成的意思,就是编译器自动实现getter和setter函数。


3. 点语法

self.identify = 1;  //设置器  相当于[person setIdentify:1];   调用setIdentify方法
self.identify;        //访问器   相当于[person identify];   调用identify方法

    点语法是编译器级别
    项目中如果想用点语法,必须在项目中的.h文件和.m文件中声明和实现 setIdentify和 identify方法,也就是说要声明和实现getter和setter方法

本文来源:http://www.bbyears.com/shoujikaifa/82540.html