【OC】-<合成存取方法And属性的的访问>

合成存取方法

为什么要合成 存 - 取 方法

  • 前介绍了良好的封装,对每个对象的成员变量都设置一个setter方法来访问他,这种做法虽然很白=准但是一旦我们包含了更多的成员变量的时候为每个变量写一个setter 和 getter 方法是很麻烦
  • 从Objective-C 2.0版本开始,它自动合成了setter方法和getter方法。
    让系统自动合成setter和getter方法只要如下两步。
  • 在类接口部分使用@property指令定义属性。

  • 在类实现部分使用@synthesize指令声明该属性。
    当采用上述两个步骤合成存取方法之后,不仅会合成成对的stter和getter方法,还会自动在类实现部分定义一个与getter方法同名的成员变量。

     Xcode编码规范推荐奖成员便利囊定义为下划线开头
     @synthesize window = _window;
          这个代码告诉编译者 合唱的property 对应的成员变量 是_window 
     @synthesiz 语法如下
         @synthesize property 名[= 成员变量名]
    

合成存取的实例

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface FKuser : NSObject
@property (nonatomic) NSString* name;
@property NSString* pass;
@property NSDate* birth;
@end

NS_ASSUME_NONNULL_END

#import "FKuser.h"

@implementation FKuser
// 为三个变量合成setter与getter方法
// 我们指定 name = _name 对name property属性进行而外控制
 @synthesize  name = _name;
 @synthesize  pass;
 @synthesize  birth;
- (void) setName :(NSString*) name {
    self->_name = [NSString stringWithFormat:@"+++%@" , name];
}
@end

#import <Foundation/Foundation.h>
#import "FKuser.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        FKuser * user = [[FKuser alloc] init];
        [user setName:@" 勒布朗"];
        [user setPass:@"0120"];
        [user setBirth:[NSDate date]];
        NSLog(@"NBA球星 %@ 的生日为 %@ 序号为%@", [user name], [user pass], [user birth]);
    }
    return 0;
}

在这里插入图片描述

额外的操作-指示符

何为引用计数

    引用计数是Objective-C 内存回收的概念,
        当一个对象的引用计数大子0时表明该对象还不应该被回收。由于 NSinteger等基础类型,以及short. float. double、
        结构体等各种C数据类型都不存在内存回收的问题,因此使用assign 即可
    • assign

    该指示符指定对属性只是进行简单赋值,不更改对所赋的值的引用计数。这个 指示符主要适用于 NSInteger 等基本类型,以及short、float、double、结构体等各种C 数据类型

    • atmoic(nonatomic)
      指定合成的存取方法是否为原子操作。所谓原子操作,主要指是否线程安全。如果使用 atomic,那么合成的存取方法都是线程安全。当一个线程进入存取方法的方法体之后,其他线程无法进入该存取方法,这样就可以避免多线程并发破坏对象的数据完整性,atomic 是默认值。虽然 atomic可以保证对象数据的完整性,但atomic 的线程安全会造成性能下降,因此,在大多数单线程环境下
      使用nonatomic 来提高存取方法的访问性能。
    • copy
  • 如果使用copy 指示符,那么当调用setter 方法对成员变量赋值时,会将被赋值
    的对象复制一个副本,再将该副本赋值给成员变量。copy 指示符会将原成员变量所引
    用对象的引用计数减 1。当成员变量的类型是可变类型,或其子类是可变类型时,被
    赋值的对象有可能在赋值之后被修改,如果程序不需要这种修改影响 setter 方法设置
    的成员变量的值,此时就可考虑使用copy 指示符

    • readonly 和 readwrite:
      readonly 指示系统只合成getter 方法,不再合成 setter 方法:readwrite
      是默认值,指示系统需要合成 setter、getter 方法。
    • retain
  • retain:使用 retain 指示符定义属性时,当把某个对象赋值给该属性时,该属性原来所
    引用的对象的引用计数减 1,被赋值对象的引用计数加 1。
    当系统启用ARC机制的时候就不需要或者很少使用retain

    • strongweak
  • strongl指示符指定该属性对被赋值对象持有强引用,而 weak 指示符指
    定该属性对被赋值对象持有弱引用。

  • -------强引用的意思是,只要该强引用指向被赋值的对
    象,那么该对象就不会自动回收

    -------弱引用的意思是,即使该弱引用指向被赋值的对象,
    该对象也可能被回收。

注意

在启动 ARC 机制时,使用strong、weak 指示符将十分方便。如果程序不希望
被该属性引用的对象被回收,那就应该使用strong 指示符;如果程序需要保证性能,
避免内存溢出,则可以使用 weak 指示符。使用 weak 指示符时需要小心,
当程序通过该weak 属性來访问被引用的对系时,该对象可能已经被回收了。对于声明为 1
weak 的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil,这样能有效的防治悬空指针,weak指示符可有效的防止悬空指针

  • unsafe_unretained
    unsafe unretained!这个指示符与 weak 指示符基本相似,对于只被 unsafe unretained
    指针所指向的对象,该对象也可能被回收。与 weak 指针不同的是,当 unsafe unretained
    指针所引用的对象被回收后,unsafe unretaincd 指针不会被赋值为 nil,因此这可能导
    致程序崩溃。一般来说,使用 unsafe unretained 指示符不如使用 weak 指示符。

copy字符 实例

不引用copy

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN
//copy实例
//NSString 有一个可变的 NSMutableString 子类

@interface fk : NSObject
//
@property (nonatomic) NSString *name;

@end

NS_ASSUME_NONNULL_END

#import "fk.h"

@implementation fk
//其实在xcode4.0之后此处已经不需要 @synthesize name了系统就已经自动合成存取方法
@synthesize name;


@end

#import <Foundation/Foundation.h>
#import "fk.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        fk * book = [[fk alloc] init];
        NSMutableString* str = [NSMutableString
             stringWithString:@"疯狂3g!"]  ;
        [book setName:str]; //第一次为book 的name属性赋值域
        NSLog(@"book  的 name 为: %@", [book name]);
        [str appendString:@"西安邮电大学的iOS俱乐部"];
        //修改了str字符串
//        当我们么有在类接口地方加上copy定义的时候,此时的给str再次复制会改变子类
//        NSMutableString的内容
        NSLog(@"book 的 name 名字为 %@", [book name]);
        
    }
    return 0;
}


在这里插入图片描述

引用copy

@interface fk : NSObject
//
@property (nonatomic,copy) NSString *name;

@end

在这里插入图片描述


对于copy的理解

当在接口部分加上 copy的时候 [book setName:str]的操作会讲把str指向的子类复制出来一个副本,再将副本作为setname的参数值 这样子再次修改str的值的时候 book的name属性不会改变

使用点语法

对于频繁使用setter 和getter语法来获取和引用对象的属性 OC语言专门设置了类似于c语言结构体一样的点语法

点语法实例

 #import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface fkcard : NSObject

@property (nonatomic, copy) NSString *color;
@property (nonatomic, copy) NSString *name;
@end

NS_ASSUME_NONNULL_END


#import "fkcard.h"

@implementation fkcard
//前面提到了不用程序一样运行
//@synthesize name;
//@synthesize color;
@end

#import <Foundation/Foundation.h>
#import "fkcard.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        fkcard *card = [[fkcard alloc] init];
        card.color = @"red";
        card.name = @"桃心";
        NSLog(@"这张牌的名字为 %@, 颜色为 %@", card.name, card.color);
    }
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值