OC个人学习笔记

协议 本质是一些方法的列表
通过
@protocol Mydelegate
-(void)walk;
-(void)run;
-(void)eat;
@end

进行声明(创建一个新的h文件在其中进行声明,通常没有对应的cpp文件),其中NSObject是一个基础协议(类似于其对应的类是所有类的基类)
协议名称一般以*delegate形式命名

与协议类似,实现对类功能扩展的还有 继承、类别、类扩展、协议 一共四种

协议的用法
1.协议的定义,即按照上述方式在delegate的protocol中进行定义,列举遵守该协议类应具备的方法列表
2.协议的遵守,在需要遵守该协议类的头文件中约定
@interface Student : NSObject
@end
3.协议的实现,在类实现中对协议中的方法进行实现
默认(默认使用@required关键词,必须实现)在protocol中公布的方法都需要在implement中进行实现,也可以通过@optional关键词声明可选择实现方法(未必一定实现)

深浅拷贝及协议的使用

深浅拷贝的对象(指针对象,基础数据类型不存在此概念)
深拷贝:拷贝出的新对象再申请一块内存空间并进行拷贝
浅拷贝:没有新内容空间的建立,仅将新对象的指针指向被复制对象

oc内存管理中的retain和release

OC使用引用计数来管理内存,每一个继承NSObject的对象,内部都维护了一个引用计数器retainCount,当对象创建时(调用alloc或者new)引用计数器会+1, 手动调用retain()方法可以使引用计数器+1,手动调用release()方法可以使引用计数器-1,当引用计数器为0时,对象会自动调用"析构函数" dealloc()方法来回收资源和释放内存。
这样当一个对象被多个地方使用和管理时,可以通过retain()将引用计数器+1,来获取使用权限(防止其他使用者释放该对象),用完了之后再通过调用release()将引用计数器-1来放弃使用权限(此时如果引用计数器为0,说明没有其他地方再使用该对象了,直接会被释放,如果引用计数器不为0,则证明还有其他地方再使用这个对象,该对象不会被释放)。这是一种设计非常优雅的内存管理机制,谁使用谁retain()用完之后release(),如果已经没有人使用它了,引用计数器为0,则释放掉。

MRU与ARU:
是oc管理内存的方式,对程序中的对象进行引用计数(通过引用计数器),每当有对象被开始使用时+1,使用完毕-1,当计数器为0时释放对象。
自动引用计数ARC:
手动引用计数MRC:
两个关键字:
retain:针对对象类型,是浅拷贝;用法 Person *p2 = [p retain](省略的写法只写Person *p2 = p,但这样仿佛不会进行引用计数,故规范写法应是加上retain)【即通常的将现有对象直接赋值给新建对象指针(为什么是新建对象的指针?因为OC的对象都是动态分配在堆中,只能通过指针访问)的操作,都是浅拷贝(问题来了,如何进行深拷贝呢,请看下一个copy关键词)】;
copy:针对NSString等,是深拷贝,具体分为copy和mutablecopy(可变拷贝与不可变拷贝),该方法是通过拷贝协议实现的。
例如,OC中的NSString类遵守了拷贝协议(NSCopying协议、NSMutableCopying协议),因此可以进行拷贝操作如下。

//顺带提下 oc中nsstring的两种初始化方法
//1.实例方法,需要手动release
NSString *str = [NSString alloc]initWithFormat:@"%@",@"hello world"]
//2.类方法,自动release
NSString *str = [NSString stringWithFormat:@"%@",@"Hello World"]

//不过一般初始化还是用最简单的
NSString *str = @"hello world";
  • 但是NSString直接使用上述@“helloworld”进行初始化,字符串并不创建在堆区,难以管理其生命周期,因此常用 NSString *str = [@“helloworld” copy]进行深拷贝,方便生命周期管理。

对上述的str对象,可进行拷贝操作如下

//1.不可变拷贝,拷贝的对象不可变
NSString *str_1 = [str copy];
//2.可变拷贝,拷贝的对象是副本,是可变的
NSString *str_1 = [str mutablecopy];

但是对于我们自定义创建的类,iOS默认并没有遵守这上述两个拷贝协议。
如果想自定义一下copy 那么就必须遵守NSCopying协议,并且手动在类中实现 copyWithZone: 方法;
如果想自定义一下mutablecopy 那么就必须遵守NSMutableCopying协议,并且手动在类中实现 mutableCopyWithZone: 方法。

copy协议中的NSCopying和NSMutableCopying方法
//1.copy
@protocol NSCopying
- (id)copyWithZone:(nullable NSZone *)zone;
@end

//2.mutablecopy
@protocol NSMutableCopying
- (id)copyWithZone:(nullable NSZone *)zone;
@end

//拷贝一个自定义的Person类对象,在implement中实现上述协议方法
- (id)copyWithZone:(nullable NSZone *)zone{
    // 默认写法,创建一个新的类
    Person *p = [[self class]allocWithZone:zone];
    // 创建同样的类属性
    p.name = self.name;
    p.age = self.age;
        // 类中如果持有自定义对象,则也需要通过copy方法进行深拷贝,如下(moto为Person中持有的moto类)
    p.moto = [self.moto copy];
    
    return p; 
}

// 之后就可以在主函数中copy该对象
Person *sxg = [Person new];
Person *shk = [sxg copy];

附注:对上述代码中的几个陌生地方做下注释

  • nullable:是一个属性/参数/方法的修饰关键词。来源是在swift语言中,实现了可以通过符号?和!修饰一个对象和方法是否为optional还是non-optional。OC为了兼容该特性,引入nullable和nonnull关键词,但演变出了三种写法,作用基本等同(对于属性、方法返回值、方法参数的修饰,建议使用:nonnull/nullable;
    对于 C 函数的参数、Block 的参数、Block 返回值的修饰,建议使用:_Nonnull/_Nullable,建议弃用 __nonnull/__nullable。)。
    • nullable(__nullable、_nullable):表示对象可以是 NULL 或 nil
    • nonnull(__nonnull、_nonnull):表示对象不应该为空
//1.方法返回值修饰:
- (nullable NSString *)method;
- (NSString * __nullable)method;
- (NSString * _Nullable)method;

//2.声明属性的修饰:
@property (nonatomic, copy, nullable) NSString *aString;
@property (nonatomic, copy) NSString * __nullable aString;
@property (nonatomic, copy) NSString * _Nullable aString;

//3.方法参数修饰:
- (void)methodWithString:(nullable NSString *)aString;
- (void)methodWithString:(NSString * _Nullable)aString;
- (void)methodWithString:(NSString * __nullable)aString;
  • NSZone是什么?(可先了解下一条cocoa是什么)是cocoa程序中的内存池概念(NSZone是Apple用来分配和释放内存的一种方式,它不是一个对象,而是使用C结构存储了关于对象的内存管理的信息),cocoa会默认配置一个NSZone,所有对象的alloc和dealloc默认都是在这个NSZone中进行的,但弊端是全局范围会导致内存碎片化。因此在需要大量的创建/释放object时,cocoa提供了可自定义的NSZone。
  • cocoa。是苹果的一套工具框架,核心包括三个框架Fouundation(核心框架)、Application Kit(macOS)、UIKit(iOS)。来源是最初苹果收购NS公司的操作系统作为其操作系统,该操作系统中带的开发套件几经改名,最后叫cocoa,也是其中类均以NS开头的缘由。

自定义对象的拷贝

description方法

沙盒路径

应用程序安装在不同手机时,程序文件路径会变化,沙盒路径应用而生。对文件的操作主要是读和写:
读文件:通过NSBundle,NSBundle这个类其实就是用来定位可执行资源的。获取到具体的可执行文件的位置,然后再加载。但是通过NSBundle读取的资源文件通常不可进行写入,若需创建新文件或写入文件请看下条。
写文件:通过NSString *homePath = NSHomeDirectory()获取文件资源路径,下面有三个文件夹document、library、tmp可供开发者写入。

  • nsmutablearray,存储的是对象类型,对基本数据类型无法存放。

值类型 指针类型(引用类型)

类的复合,仅是一种程序设计方法原则,目的是方便地追加类的功能

%p 对象的地址
%@ 对象(例如字符串对象)
%d 整型
%lu 无符号长整型

@class
#import “Person.h”

1.成员对象向调用对象返回消息

2.委托模型,正向委托

3.反向委托

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值