关联对象
- ObjcAssociation 结构体保存了关联policy和关联value
- ObjcAssociationMap 以关联key为key ,以 ObjcAssociation 为 value
- ObjcAssociationHashMap 为全局的 map。其中 key为关联对象的伪装指针。value 为 ObjcAssociationMap
KVO
- 当给A的实例添加observer的时候,系统动态创建名为 NSKVONotifying_A 的A的子类。
- NSKVONotifying_A 重写了父类的setter方法。
- setter方法的前后添加了 willChangeValueForKey 和 didChageForKey 。
- A的 instance 的 isa 指针指向NSKVONotifying_A这个类。
- 当调用A的setter方法的时候,由于isa指针指向了NSKVONotifying_A,所以会调用 NSKVONotifying_A 的setter方法,NSKVONotifying_A的setter方法中调用super的setter方法,这时候会调用A的setter方法。
- 调用setValue: forKey 会调用对应的setter方法,所以对KVO有效
#KVC
- 调用 valueForKey 时,会判断 相关getter方法是否存在,如果存在直接调用
- 如果不存在,会调用 +(BOOL)accessInstanceVariablesDirectly 方法。
- 方法返回如果方法返回NO,说明不允许访问成员变量,会抛出一个NSUnknownKeyException 的异常。
- 如果方法返回YES,说明可以访问成员变量,然后判断没有对应的成员变量,判断顺序依次为: _key key _isKey isKey。如果找到了。直接访问。
- 调用 setValue: forKey 也会调用 +(BOOL)accessInstanceVariableDirectly 进行判断是否可以访问成员变量。
Block
- __NSGlobalBlock__ 调用 copy 操作什么也不做,因为本来就在代码区,复制那么多也没用。
- __NSMallocBlock__ 调用 copy 操作引用计数+1,本来就在堆里,复制多了也没用,引用计数+1 即可。
- __NSStackBlock__ 调用 copy 操作复制到堆上,变成堆block。为了防止函数返回后销毁,所以放到堆里。
ARC环境下,什么情况下编译器会把 stack 上的block复制到 heap上
- block 作为函数返回值。
- 将block 复制给 __strong 指针。
- block作为usingblock时。
- block作为GCD API的方法参数时。
UIView -(void)sizeToFit
-
Resizes and moves the receiver view so it just encloses its subviews.
-
Call this method when you want to resize the current view so that it uses the most appropriate amount of space. Specific UIKit views resize themselves according to their own internal needs. In some cases, if a view does not have a superview, it may size itself to the screen bounds. Thus, if you want a given view to size itself to its parent view, you should add it to the parent view before calling this method. You should not override this method. If you want to change the default sizing information for your view, override the sizeThatFits: instead. That method performs any needed calculations and returns them to this method, which then makes the change.
@property(nonatomic,getter=isExclusiveTouch) BOOL exclusiveTouch API_UNAVAILABLE(tvos); // default is NO
A Boolean value that indicates whether the receiver handles touch events exclusively.
UISrollView 属性
- keyboardDismissMode
The manner in which the keyboard is dismissed when a drag begins in the scroll view.
- delaysContentTouches
A Boolean value that determines whether the scroll view delays the handling of touch-down gestures.
- canCancelContentTouches
A Boolean value that controls whether touches in the content view always lead to tracking.
- - (BOOL)touchesShouldCancelInContentView:(UIView *)view;
The scroll view calls this method just after it starts sending tracking messages to the content view. If it receives NO from this method, it stops dragging and forwards the touch events to the content subview. The scroll view does not call this method if the value of the canCancelContentTouches property is NO.
方法查找失败后处理流程
-
首先根据方法是类方法还是实例执行
+ (BOOL)resolveClassMethod:(SEL)sel
或者+ (BOOL)resolveInstanceMethod:(SEL)sel
进行第一步拯救。在这个方法里可以使用class_addMethod
动态添加方法实现,返回YES代表添加上了,(亲测,如果添加了返回NO也可以执行)。如果是类方法这一步不处理直接崩溃,如果是实例方法不添加进行下一步流程。 - 执行
- (id)forwardingTargetForSelector:(SEL)aSelector
返回一个对象,可以将方法转发给他处理。否则进行下一步 - 执行
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
生成方法签名然后返回,如果没有生成方法签名,直接崩溃。生成方法签名返回后进行下一步。 - 执行
- (void)forwardInvocation:(NSInvocation *)anInvocation
转发 NSInvocation,重写这个方法可以指定一个对象来执行 invocation,也可以什么都不做也不会崩溃,如果交给super处理依然会崩溃。
- 通过查看内存发现 方法( SEL)就是一个字符串指针,只不过是以小数点结尾来进行分割不同的方法名。