提示:由于水平有限,如发现有疑问或错误的地方请毫不客气的提出、讨论,我会在第一时间回复,感谢在先
问题:当别人以继承方式扩展自己代码功能的时候,如果重写一个方法后,它是不知道应不应该先调用父类的方法,或者调用时机不确定(在业务前调用还是实现业务后调用)
解决方法:使用面向接口(暂且这么叫吧)
//父类@protocol SuperObjectProtocol//option内容是可选实现,require 是必须实现.以协议中可选实现或必须实现的方法替代在interface覆写的方法.@optional- (void)optionalOverrideMethod;@require- (void)mustOverrideMethod; @end@interface SuperObject:NSObject@property (strong, nonatomic) id child;//可以约定interface中的方法子类不能覆写;覆写的方法只能是协议中- (void)doSth;@end @implementation SuperObject- (instancetype)init { if (self = [super init]) { self.child = self; } return self;}- (void)testOptionOverrideMethod{ if ([self.child respondsToSelector:@selector(optionOverrideMethod)]) { //self.child 和 self 是同一个对象.引入child 促使协议中的方法在父类可见.可以直接调用[self.child optionOverrideMethod]. 而使用 [self performSelector:@selector(customMethod)];也可以,但并不好. [self.child optionOverrideMethod]; }}- (void)testMustOverrideMethod { if ([self.child respondsToSelector:@selector(mustOverrideMethod)]){ [self.child mustOverrideMethod]; }}//子类.@interface SubObject:SuperObject @end @implementation SubObject- (void)optionOverrideMethod { NSLog("可选实现的接口方法");}- (void)mustOverrideMethod { NSLog("必须实现的接口方法")}@end //调用SubObject* sub = [SubObject alloc]init];[sub testOpitionOverrideMethod]; // 可选实现的接口方法[sub testMustOverrideMethod]; // 必须实现的接口方法总结:面向接口可以使方法的定义和方法的实现分离.@end
2.cocoaPods中Podfile书写中的版本号应该注意的.
今天看pods官网guide文档文档是发现一个问题.In addition to the logic operators CocoaPods has an optimistic operator ~>:
'~> 0.1.2' Version 0.1.2 and the versions up to 0.2, not including 0.2 and higher'~> 0.1' Version 0.1 and the versions up to 1.0, not including 1.0 and higher'~> 0' Version 0 and higher, this is basically the same as not having it.比如 ~>0.3 之前的理解是它和 version >= 0.3 是等价的(错误理解).版本语义解释: major(主版本).minor(次版本).patch(补丁版本) patch:如果修复了bugs,(一般能够保障接口向后兼容). minor:添加新的功能,(接口向后兼容有可能没有保障) major:重大修改(接口有可能修改,向后兼容没有保障) 根据版本号最右边的字段进行升级(上面例子已经很好解释).
值得一看的介绍视频:https://www.youtube.com/watch?v=x4ARXyovvPc(翻墙?)[链接描述][1]
3.Label显示的内容如果是nil;则会显示(null);工程中要避免这种情况的发生.
4.通过指定数组元素多少的类方法来创建可变数组,应该注意其索引是否越界
NSMutableArray* testMutArray = [NSMutableArray arrayWithCapacity:5]; [testMutArray insertObject:@3 atIndex:1]; //崩溃原因是arrayWithCapacity只是提示其大小为5,它并不会像c数组那样创建实际的存储空间. Note that NSArray objects are not like C arrays. That is, even though you specify a size when you create an array, the specified size is regarded as a “hint”; the actual size of the array is still 0. This means that you cannot insert an object at an index greater than the current count of an array. For example, if an array contains two objects, its size is 2, so you can add objects at indices 0, 1, or 2. Index 3 is illegal and out of bounds; if you try to add an object at index 3 (when the size of the array is 2), NSMutableArray raises an exception
5.关于autoReleasePool:
(1在没有手加Autorelease Pool的情况下,Autorelease对象是在当前的runloop迭代结束时释放的,而它能够释放的原因是系统在每个runloop迭代中都加入了自动释放池Push和Pop(2使用容器的block版本的枚举器时,内部会自动添加一个AutoreleasePool: [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {// 这里被一个局部@autoreleasepool包围着}]; 在普通for循环和for in循环中没有,for循环中遍历产生大量autorelease变量时,就需要手加局部AutoreleasePool
6.frame 和 autolayout同时使用:
If you set a view's translatesAutoresizingMaskIntoConstraints = YES, then calls to setFrame: are automatically translated at runtime into layout constraints based on the view's current autoresizingMask. This lets you mix frame-based layout with constraint-based layoutFor instance you could use Auto Layout to define the layout of all of the subviews of a view, but still call setFrame: to set the size and position of the view itself. From your perspective, you're doing layout with a mix of Auto Layout and direct frame manipulation. But the system is actually using constraints to handle everythingHowever, there is one big caveat(警告) about using translatesAutoresizingMaskIntoConstraintsWhen you do this, you still need to make sure that these automatic constraints can be satisfied with the rest of your constraints.So, for instance, suppose there are already constraints that determine the size and position of your view, and then you also set translatesAutoresizingMaskIntoConstraints = YES and called setFrame:. The call to setFrame: will generate new constraints on the view, which will probably conflict with the already existing constraints.(In fact, this error happens often. If you ever see a log message complaining about conflicting constraints, and one of those constraints is a NSAutoresizingMaskLayoutConstraint, then what you're seeing is a conflict with an automatic constraint. This is an easy mistake, because translatesAutoresizingMaskIntoConstraints = YES is the default value, so if you're configuring constraints in code you need to remember to turn it off if you don't want these automatic constraints.)In contrast, suppose again that there are already existing constraints that determine the size and position of your view, but then you set translatesAutoresizingMaskIntoConstraints = NO before you call setFrame:. In this case, your setFrame: calls would not produce new constraints, so there would be no conflict between separate constraints. However, in this case, there is still a "conflict" between the constraints and the frame value you set. At the next time Auto Layout is invoked, it would see the already existing constraints on the view, calculate the frame value which they require, and set the frame to the required value itself, clobbering the value you set manually.在实际的项目中一般frame 与 autolayout 同时使用的情况则少,根据不同的情况设置translatesAutoresizingMaskIntoConstraints
shallowCopy && mutableCopy
不管是集合类对象,还是非集合类对象,接收到copy和mutableCopy消息时,都遵循以下准则: copy返回imutable对象;mutableCopy返回mutable对象; (1)对于非集合类型 [immutableObject copy] // 浅复制 [immutableObject mutableCopy] //深复制 [mutableObject copy] //深复制 [mutableObject mutableCopy] //深复制 (2)集合类型 [immutableObject copy] // 浅复制 [immutableObject mutableCopy] //单层深复制 [mutableObject copy] //单层深复制 [mutableObject mutableCopy] //单层深复制 如果实现容器的深拷贝? (1)对于集合使用initWithXXXX:copyItems: 将第二个参数设置为YES即可深复制NSDictionary shallowCopyDict = [[NSDictionary alloc] initWithDictionary:someDictionary copyItems:YES]; (2)集合进行归档(archive),然后反解档(unarchive) NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]]; (3)遍历容器,把容器里面的对象添加到新的容器中;