Objective-C
Foundation
Runtime
- objc_msgSend

- Method Swizzling
当使用Method Swizzling时,如下代码中调用[self swizzed_method]相当于调用替换之前的[self method]
- (void)swizzed_method {
[self swizzed_method];
}
Objective-C中集合类簇实际对应的对象类型。
| 类 | 对应的类簇 |
|---|---|
| NSArray | __NSArrayI |
| NSMutableArray | __NSArrayM |
| NSDictionary | __NSDictionaryI |
| NSMutableDictionary | __NSDictionaryM |
Equality
一个isEqual的判断示例:
- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}
if (![object isKindOfClass:[NSArray class]]) {
return NO;
}
return [self isEqualToArray:(NSArray *)object];
}
isEqual的判定结果与hash无关;对于
NSArray对象,只要其子项满足isEqualToString,isEqualToDictionary等值比较,isEqual返回YES;同时NSArray的containsObject:(id)object判断的结果由与objectisEqual的返回值决定;对于
NSMutableArray对象,调用removeObject:(id)object,一旦子项中的对象与objectisEqual返回YES,该子项将被移除。
由于字符串驻留优化技术, 所有静态定义的不可变字符串对象 ,如果字符串表意相同,那么这些对象都指向同一个驻留字符串值,其类型为__NSCFConstantString。
// 静态定义
NSString *a = @"Hello";
NSString *b = @"Hello";
BOOL wtf = (a == b); // YES
// 非静态定义
NSString *c = [NSString stringWithFormat:@"Hello"];
BOOL ass = (a == c); // NO
泛型
定义
泛型可用于制定容器中对象的类型:
NSArray<NSString *> *strings = @[@"sun", @"yuan"];
NSDictionary<NSString *, NSNumber *> *mapping = @{@"a": @1, @"b": @2};
协变性和逆变性(似乎只能在自定义泛型中使用)
不指定类型的容器可以喝任意泛型类型转化,但指定泛型类型之后,两个不同类型之间不能强转,需要通过__covariant,__contravariant修饰;
__covariant- 协变性,子类型可以强转到父类型(里氏替换原则)eg:NSArray <NSString *>类型的对象赋值给NSArray__contravariant- 逆变性,父类型可以强转到子类型(WTF?)eg:将一个NSArray的对象赋值给NSArray<NSNumber > *对象
类型检查
__kindof相对于id更加具体的制定了对象的类型:
@property (nonatomic, readonly, copy) NSArray<__kindof UIView *> *subviews;
在调用时也不需要强转类型,同时也不会有编译警告:
UIButton *button = [view.subviews lastObject];
isKindOfClass && isMemberOfClass
isMemberOfClass 判断是否是某个类的成员;
isKindOfClass 判断是否是某个类或其子类的成员;
API Reference
Navigation Bar
修改UIStatusBarStyle
IOS 7 OR LATER
info.plist 设置
UIViewControllerBasedStatusBarAppearance为YES;在UIViewController中重写
preferredStatusBarStyle,并在需要改变UIStatusBarStyle时调用[self setNeedsStatusBarAppearanceUpdate];在UINavigationController重写
preferredStatusBarStyle方法,返回topViewController的UIStatusBarStyle。
(UIStatusBarStyle)preferredStatusBarStyle {
UIViewController *viewController = self.topViewController;
return [viewController preferredStatusBarStyle];
}
info.plist 设置
UIViewControllerBasedStatusBarAppearance为NO;直接调用
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault修改statusBarStyle。
UINavigationBar属性
edgesForExtendedLayout设置ViewController延伸的枚举,默认UIRectEdgeAll,ViewController视图会延伸到UINavigationBar和UITabBar,UIRectEdgeNone则不会延伸。automaticallyAdjustsScrollViewInsets默认YES,视图初始状态从UINavigationBar下面开始,从UITabBar顶部结束,当edgesForExtendedLayout属性设置为UIRectEdgeAll时,视图可以穿透UINavigationBar和UITabBar,作用相当于自动设置了contentInsets。extendedLayoutIncludesOpaqueBars属性是对edgesForExtendedLayout的补充,当 NavigationBar、TabBar、TooBar 不透明 时 ,设置为YES,视图任将扩展到不透明区域,设置为NO,则不会扩展到不透明区域。modalPresentationCapturesStatusBarAppearance控制在present一个viewController时,是否由被present的viewController控制statusBarStyle,默认为NO。
自定义UINavigationBar样式
设置阴影线条image
// 隐藏阴影黑线 [self.navigationController.navigationBar setShadowImage:[[UIImage alloc] init]]; // 显示阴影黑线 [self.navigationController.navigationBar setShadowImage:nil];设置背景图片
[self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
Tips
宏与静态常量
定义常量
.h //
extern NSString * const kConstExternFoo;
.m //
NSString * const kConstExternFoo = @"ConstExternFoo";
static全局变量 & static局部变量
局部变量:static修饰的局部变量延长了该变量的生命周期,任然只能局部访问,但当再次调用该局部区域(函数)时,该变量存储的是上次调用该局部区域的值,相当于只能"局部访问"的全局变量;
全局变量:static修饰的全局变量限制了该变量只能在该文件中访问。