一、init的实现
-
代码
- (instancetype)init { if (self = [super init]) { // 给属性赋值 _xxx = @"xxx"; } return self; } -
为什么用
instancetype而不用id-
区别1:
instancetype用来在编译期确定实例的类型- 而使用
id的话,编译期不检查类型,运行时检查类型
-
区别2:
id可以作为方法的参数instancetype不可以,instancetype只适用于初始化方法和便利构造器的返回值类型
-
-
扩展1:手写一个类
// Person.h @interface Person : NSObject @property (nonatomic , strong , readonly)NSString *name; @end// Person.m #import "Person.h" @interface Person () @property (nonatomic , strong , readwrite)NSString *name; @end @implementation Person - (instancetype)initWithName:(NSString *)name { if (self = [self init]) { _name = name; } return self; } @end -
扩展2:手写分类
// Person+Net.h #import "Person.h" @interface Person(Net) @property(nonatomic,copy)NSString *nickName; @end // Person+Net.m #import "Person+Net.h" #import <objc/runtime.h> static NSString *nickNameKey = @"nickNameKey"; //一个属性定义一个 @implementation Person(nickName) -(void)setStr:(NSString *)str { objc_setAssociatedObject(self, &nickNameKey, str,OBJC_ASSOCIATION_COPY); /* strong修饰的类型用 OBJC_ASSOCIATION_RETAIN_NONATOMIC copy 修饰的类型用 OBJC_ASSOCIATION_COPY assin 修饰的类型用 OBJC_ASSOCIATION_ASSIGN */ } -(NSString*)str { return objc_getAssociatedObject(self, &nickNameKey); } @end -
扩展3:手写单例
// ChangeNameEngine.h @interface ChangeNameEngine : NSObject +(instancetype)shareManager; @end// ChangeNameEngine.m #import "ChangeNameEngine.h" @implementation ChangeNameEngine + (instancetype)shareManager { static ChangeNameEngine *shareManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ shareManager = [[ChangeNameEngine alloc] init]; }); return shareManager; } @end -
补充:OC中的static
-
局部变量
// age没有被static修饰的时候 - (void)Aboutstatic { int age = 21; age--; NSLog(@"age==%d",age); } - (void)viewDidLoad { [super viewDidLoad]; //在此打印三次结果,看看输出 [self Aboutstatic]; [self Aboutstatic]; [self Aboutstatic]; } //控制台输出结果可以看到,变量age每次都被初始化为21,所以三次打印结果都为20 2016-01-15 14:41:47.907 [1754:258152] age==20 2016-01-15 14:41:47.908 [1754:258152] age==20 2016-01-15 14:41:47.908 [1754:258152] age==20 //age通过static修饰之后 - (void)Aboutstatic { static int age = 21; age--; NSLog(@"age==%d",age); } //看看控制台输出结果 2016-01-15 14:49:58.475 [1768:266933] age==20 2016-01-15 14:49:58.476 [1768:266933] age==19 2016-01-15 14:49:58.476 [1768:266933] age==18- 只会被初始化一次,也就是只有一份内存。
- 生命周期被改变,一直到程序结束才释放
-
全局变量
// 1.第一个类中声明一个全局变量和一个方法 int age_ = 21; - (void)logAge { NSLog(@"age_==%d",age_); } 2.在第二个类中使用extern来访问age_ extern int age_; NSLog(@"%d",age_); 看到控制台打印输出 2016-01-15 15:26:50.224 [1810:289550] 21 // 2.被static修饰的情况下 static int age_ = 21; 当继续使用extern引用的时候,就会报错 Undefined symbols for architecture x86_64: "_age_", referenced from: -[2eController viewDidLoad] in 2Controller.o 错误是说在引用age_的时候,找不到这个变量,是因为使用了static修饰,所以除了第一个类自己除外,都访问不到-
默认情况没有被static修饰的情况下 ①作用域是整个项目,项目中任何地方都能通过extern关键字来引用 ②还是只会被初始化一次,内存地址同样只有一份
-
被static修饰的情况下
①作用域只限于当前文件,项目中任何地方都不能通过extern关键字来引用 ②改变了作用域,但是没有改变生命周期
-
-
二、非对称加密原理
- 对称加密:知道如何加密的同时,便知道如何解密
- RSA(非对称加密):即使知道了如何加密(公钥),也不知道如何解密(私钥)
- 例:两个质数的积为公钥,这两个质数为私钥
- 如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
- 情景:
- 乙方生成一对密钥(公钥和私钥)并将公钥向其它方公开。
- 得到该公钥的甲方使用该密钥对机密信息进行加密后再发送给乙方。
- 乙方再用自己保存的另一把专用密钥(私钥)对加密后的信息进行解密。乙方只能用其专用密钥(私钥)解密由对应的公钥加密后的信息。
- 在传输过程中,即使攻击者截获了传输的密文,并得到了乙的公钥,也无法破解密文,因为只有乙的私钥才能解密密文。
- 同样,如果乙要回复加密信息给甲,那么需要甲先公布甲的公钥给乙用于加密,甲自己保存甲的私钥用于解密。
三、不用set和get方法如何设置或获取属性的值
四、int转64位字符串,怎么实现
-
解答:
string toHex(int num1) { if (num1 == 0) return "0"; unsigned int num = num1; string result = ""; while (num > 0) { result.push_back(num % 16 > 9 ? num % 16 - 10 + 'a' : num % 16 + '0'); num /= 16; } reverse(result.begin(),result.end()); return result; }
五、Layer和view的关系
UIView有个layer属性,可以返回它的主CALayer实例,UIView有一个layerClass方法,返回主layer所使用的 类,UIView的子类,可以通过重载这个方法,来让UIView使用不同的CALayer来显示 -UIView实现了CALayer的delegateUIView本身,更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等等,实际上内部都是在访问它所包含的CALayer的相关属性。UIView的CALayer类似UIView的子View树形结构,也可以向它的layer上添加子layer,来完成某些特殊的表示- 区别
- 首先UIView可以响应事件,CALayer不可以响应事件
- 一个 Layer 的 frame 是由它的 anchorPoint,position,bounds,和 transform 共同决定的,而一个 View 的 frame 只是简单的返回 Layer的 frame
- UIView主要是对显示内容的管理而 CALayer 主要侧重显示内容的绘制
- 在做 iOS 动画的时候,修改非 RootLayer的属性(譬如位置、背景色等)会默认产生隐式动画,而修改UIView则不会。
六、view和vc的关系
七、Readonly修饰属性,会生成set方法吗?
只读,只生成 getter 方法的声明和实现。为了达到封装的目的,我们应该只在确有必要时才将属性对外暴露,并且尽量把对外暴露的属性设为 readonly。如果这时候想在对象内部通过 setter 修改属性,可以在类扩展中将属性重新声明为 readwrite;如果仅在对象内部通过 _ivar 修改,则不需要重新声明为 readwrite。