iOS基础总结
- 如何让自己的类使用copy修饰符?如何重写copy关键字?
- 对非集合类对象的copy操作
- 集合类对象的copy与mutableCopy
- objc中向一个nil对象发送消息将会发生什么?
- objc中向一个对象发送消息[obj foo]和objc_msgSend()函数之间有什么关系?
- 什么时候会报unrecognized selector的异常?
- 一个objc对象如何进行内存布局?(考虑有父类的情况)
- 一个objc对象的isa的指针指向什么?有什么作用?
- OC中kvo的执行顺序
- 功能快捷键
- 合理的创建标题,有助于目录的生成
- 如何改变文本的样式
- 插入链接与图片
- 如何插入一段漂亮的代码片
- 生成一个适合你的列表
- 创建一个表格
- 创建一个自定义列表
- 如何创建一个注脚
- 注释也是必不可少的
- KaTeX数学公式
- 新的甘特图功能,丰富你的文章
- UML 图表
- FLowchart流程图
- 导出与导入
如何让自己的类使用copy修饰符?如何重写copy关键字?
如何让自己的类使用copy修饰符?如何重写copy关键字?
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger,CYLSex){
CYLSexMan,
CYLsEXWoman
};
NS_ASSUME_NONNULL_BEGIN
@interface CYUser : NSObject<NSCopying>
@property(nonatomic,readonly,copy)NSString *name;
@property(nonatomic,readonly,assign)NSInteger age;
@property(nonatomic,readonly,assign)CYLSex sex;
-(instancetype)initWithName:(NSString *)name age:(NSInteger)age sex:(NSInteger)sex;
-(void)addFriend:(CYUser *)user;
-(void)removeFriend:(CYUser *)user;
@end
NS_ASSUME_NONNULL_END
#import "CYUser.h"
@implementation CYUser
{
NSMutableSet *_friends;
}
/**
属性的setter方法,因为name为readonly修饰,所以不会创建setter方法。
@param name <#name description#>
*/
-(void)setName:(NSString * _Nonnull)name{
//不要在setter里面进行if(_obj != obj)这样子的判断。
_name=[name copy];
}
-(instancetype)initWithName:(NSString *)name age:(NSInteger)age sex:(NSInteger)sex{
if (self=[super init]) {
_name=[name copy];
_age=age;
_friends=[[NSMutableSet alloc]init];
}
return self;
}
/**
给集合中添加用户
@param user <#user description#>
*/
-(void)addFriend:(CYUser *)user{
[_friends addObject:user];
}
-(void)removeFriend:(CYUser *)user{
[_friends removeObject:user];
}
/**
对类进行拷贝,返回copy体。
对setk进行浅拷贝
@param zone <#zone description#>
@return <#return value description#>
*/
//-(id)copyWithZone:(NSZone *)zone{
// CYUser *copy=[[[self class]allocWithZone:zone] initWithName:_name age:_age sex:_sex];
// copy->_friends=[_friends mutableCopy];
// return copy;
//}
/**
对set进行深拷贝
@param zone <#zone description#>
@return <#return value description#>
*/
-(id)copyWithZone:(NSZone *)zone{
CYUser *copy=[[[self class]allocWithZone:zone]initWithName:_name age:_age sex:_sex];
copy->_friends=[[NSMutableSet alloc]initWithSet:_friends copyItems:YES];
return copy;
}
@end
=================================================================
对非集合类对象的copy操作
在非集合类对象中:对 immutable 对象进行 copy 操作,是指针复制,mutableCopy 操作时内容复制;对 mutable 对象进行 copy 和 mutableCopy 都是内容复制。用代码简单表示如下:
[immutableObject copy] // 浅复制
[immutableObject mutableCopy] //深复制
[mutableObject copy] //深复制
[mutableObject mutableCopy] //深复制
=================================================================
集合类对象的copy与mutableCopy
在集合类对象中,对 immutable 对象进行 copy,是指针复制, mutableCopy 是内容复制;对 mutable 对象进行 copy 和 mutableCopy 都是内容复制。但是:集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制。用代码简单表示如下:
[immutableObject copy] // 浅复制
[immutableObject mutableCopy] //深复制
[mutableObject copy] //深复制
[mutableObject mutableCopy] //深复制
=================================================================
objc中向一个nil对象发送消息将会发生什么?
在 Objective-C 中向 nil 发送消息是完全有效的——只是在运行时不会有任何作用:
- 如果一个方法返回值是一个对象,那么发送给nil的消息将返回0(nil)。
- 如果方法返回值为指针类型,其指针大小为小于或者等于sizeof(void*),float,double,long double 或者 long long 的整型标量,发送给 nil 的消息将返回0
- 如果方法返回值为结构体,发送给 nil 的消息将返回0。结构体中各个字段的值将都是0
- 如果方法的返回值不是上述提到的几种情况,那么发送给 nil 的消息的返回值将是未定义的。
objc中向一个对象发送消息[obj foo]和objc_msgSend()函数之间有什么关系?
该方法编译之后就是objc_msgSend()函数调用.
什么时候会报unrecognized selector的异常?
当调用该对象上某个方法,而该对象上没有实现这个方法的时候, 可以通过“消息转发”进行解决。
objc在向一个对象发送消息时,runtime库会根据对象的isa指针找到该对象实际所属的类,然后在该类中的方法列表以及其父类方法列表中寻找方法运行,如果,在最顶层的父类中依然找不到相应的方法时,程序在运行时会挂掉并抛出异常unrecognized selector sent to XXX 。但是在这之前,objc的运行时会给出三次拯救程序崩溃的机会:
- Method resolution
objc运行时会调用+resolveInstanceMethod:或者 +resolveClassMethod:,让你有机会提供一个函数实现。如果你添加了函数,那运行时系统就会重新启动一次消息发送的过程,否则 ,运行时就会移到下一步,消息转发(Message Forwarding)。 - Fast forwarding
如果目标对象实现了-forwardingTargetForSelector:,Runtime 这时就会调用这个方法,给你把这个消息转发给其他对象的机会。 只要这个方法返回的不是nil和self,整个消息发送的过程就会被重启,当然发送的对象会变成你返回的那个对象。否则,就会继续Normal Fowarding。 这里叫Fast,只是为了区别下一步的转发机制。因为这一步不会创建任何新的对象,但下一步转发会创建一个NSInvocation对象,所以相对更快点。 - Normal forwarding
这一步是Runtime最后一次给你挽救的机会。首先它会发送-methodSignatureForSelector:消息获得函数的参数和返回值类型。如果-methodSignatureForSelector:返回nil,Runtime则会发出-doesNotRecognizeSelector:消息,程序这时也就挂掉了。如果返回了一个函数签名,Runtime就会创建一个NSInvocation对象并发送-forwardInvocation:消息给目标对象。
一个objc对象如何进行内存布局?(考虑有父类的情况)
- 所有父类的成员变量和自己的成员变量都会存放在该对象所对应的存储空间中.
- 每一个对象内部都有一个isa指针,指向他的类对象,类对象中存放着本对象的
- 对象方法列表(对象能够接收的消息列表,保存在它所对应的类对象中)
- 成员变量的列表,
- 属性列表,
- 它内部也有一个isa指针指向元对象(meta class),元对象内部存放的是类方法列表,类对象内部还有一个superclass的指针,指向他的父类对象。
- 类对象既然称为对象,那它也是一个实例。类对象中也有一个isa指针指向它的元类(meta class),即类对象是元类的实例。元类内部存放的是类方法列表,根元类的isa指针指向自己,superclass指针指向NSObject类。
一个objc对象的isa的指针指向什么?有什么作用?
指向他的类对象,从而可以找到对象上的方法
OC中kvo的执行顺序
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//执行的顺序就是willChangeValueForKey>didChangeValueForKey>addObserver
[self addObserver:self forKeyPath:@"now" options:NSKeyValueObservingOptionNew context:nil];
NSLog(@"1");
[self willChangeValueForKey:@"now"];
NSLog(@"2");
[self didChangeValueForKey:@"now"];
NSLog(@"4");
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
NSLog(@"3");
}
@end
=================================================================
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC
语法后生成一个完美的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务
- 完成任务
创建一个表格
一个简单的表格是这么创建的:
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
设定内容居中、居左、居右
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文本居中 | 第二列文本居右 | 第三列文本居左 |
SmartyPants
SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:
TYPE | ASCII | HTML |
---|---|---|
Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
Quotes | "Isn't this fun?" | “Isn’t this fun?” |
Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
创建一个自定义列表
-
Markdown
- Text-to- HTML conversion tool Authors
- John
- Luke
如何创建一个注脚
一个具有注脚的文本。1
注释也是必不可少的
Markdown将文本转换为 HTML。
KaTeX数学公式
您可以使用渲染LaTeX数学表达式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通过欧拉积分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多关于的信息 LaTeX 数学表达式here.
新的甘特图功能,丰富你的文章
- 关于 甘特图 语法,参考 这儿,
UML 图表
可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图::
这将产生一个流程图。:
- 关于 Mermaid 语法,参考 这儿,
FLowchart流程图
我们依旧会支持flowchart的流程图:
- 关于 Flowchart流程图 语法,参考 这儿.
导出与导入
导出
如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。
导入
如果你想加载一篇你写过的.md文件或者.html文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。
注脚的解释 ↩︎