22th,July,2016
前言
最近越发感觉基础掌握的很差,这篇就好好记录下关于iOS那些基础吧
NSString判空的几点思考
NSString判空
判空第一步:一般会对该字符串进行类型判断 -isKindOfClass:[NSString class]是否为NSString的实例或继承自NSString的任意类实例。也就是声明为NSString类型后,该变量的类型不一定是NSString(r: 为什么会改变呢),通常是两种情况:- 声明该变量,但未实例此时为nil;(ps: nil.length == 0)
- 另一种是将NSString的指针指向其它类型(比如NSNumber–>__NSCFNumber)。
判空第二步:去除首尾空格,获取长度<=0则为空
// 去除首尾空格 [str stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
- 扩展/类方法。
- 扩展:
扩展方法
- 扩展:
@implementation NSString (Util)
-(BOOL)isEmpty {
return (![self isKindOfClass:[NSString class]]) || [self trim].length <= 0;
}
@end
如果是针对NSString扩展方法-(BOOL)isEmpty;,则会出现一个问题,如果声明NSString变量后指向其它非NSString对象,发送isEmpty消息后“unrecognized selector sent to instance iphone“,表示NSString对象已经不存在,向它发送消息自然要报错了。
思考: 如果不是针对NSString扩展,而是针对NSObject扩张。这个问题好像就不存在了。
- 类方法:
声明一个对象,添加类方法
@implementation StringUtil
+ (BOOL)isEmpty:(NSString *)string {
return (![string isKindOfClass:[NSString class]]) || ([string trim].length <= 0);
}
@end
10th,August,2016
weakSelf && strongSelf
最近在看AFNetworking的源码,在AFNetworkReachabilityManager.m中看到-startMonitoring中有段代码是这样的:
__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf.networkReachabilityStatus = status;
if (strongSelf.networkReachabilityStatusBlock) {
strongSelf.networkReachabilityStatusBlock(status);
}
};
weakSelf我理解,是为了在Block内产生循环引用,而block内使用strongSelf我就不知道是因为什么。bang在这篇文章中做了解释AFNetworking2.0源码解析<一>:不允许self在这个执行过程中释放。block执行完后这个strongSelf会自动释放。
总结:这种写法应该是为了在Block执行过程中不要自动释放,且不存在循环引用的问题吧。
12th,August,2016
NSURL:relativeToURL
NSURL *baseURL = [NSURL URLWithString:@"https://developer.apple.com"];
NSURL *url = [NSURL URLWithString:@"foo" relativeToURL:baseURL];// https://developer.apple.com/foo
url = [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL];// https://developer.apple.com/foo?bar=baz
url = [NSURL URLWithString:@"/foo" relativeToURL:baseURL];// https://developer.apple.com/foo
url = [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // https://developer.apple.com/foo/
url = [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // https://developer.apple.com/foo/
url = [NSURL URLWithString:@"https://apple.com/" relativeToURL:baseURL];// https://apple.com/
15th,August,2016
Declaration(声明) VS Definition(定义)
- Declaration声明
声明函数或变量的存在,但不为其分配内存。 - Definition
声明函数或变量的存在,并为其分配存储空间 - 小结
1). 声明可以有多次,但定义只有一次,因为同一个变量或函数只会分配一次内存空间。
2). 声明变量时默认会分配内存,如果通过关键字extern声明变量,则不会默认分配内存。要使用该变量,遵循有声明有定义才可使用
Objective-C
extern int tmp;
int tmp = 10;
17th,August,2016
苹果命名规范
- 内部常量统一以“k”开头。
判断系统版本
#ifdef __IPHONE_7_0
// iOS7.0以上执行代码
#endif
// Availability.h
...
#define __IPHONE_9_0 90000
#define __IPHONE_9_1 90100
#define __IPHONE_9_2 90200
...
5th,Nov,2016
界面跳转
learn from : View Controller Programming Guide for iOS
1. 界面跳转:
1). 导航控制器的出入栈: [self.navigationController pushViewController]
与[self.navigationController popViewController]
。// 左右切换界面
2). 视图控制器的模态显示和消失: [self presentViewController]
与[self dismissViewController]
// 从底部升起界面
3). using Segues
4). 容器视图隐藏另一个视图
5). showViewController: 使用该方法跳转时,视图控制器无需知道是否嵌入了SplitViewController或者NavigationController。因为该方法在内部已重写,所以比如该视图控制器是navigationController,则会重写该方法 targetViewControllerForAction:sender: 在其中push vc into its navigation stack。
- (nullable UIViewController *)targetViewControllerForAction:(SEL)action sender:(nullable id)sender {
return self.navigationController;// 返回nil,则window's rootviewController会present vc modally。
}
Demo from 这里: 既用模态的方式又想让第二界面的导航栏存在
//实例化一个第二界面对象
SecondViewController *SecondVC= [[SecondViewController alloc]init];
UINavigationController *naVC = [[UINavigationController alloc]initWithRootViewController: SecondVC];
[self.navigationController presentViewController:naVC animated:YES completion:nil];
- Creating an Unwind Segue
- 声明- (IBAction)myUnwindAction:(UIStoryboardSegue*)unwindSegue方法;
- 在storyboard中拖拉对应的控件到Exit中,选择myUnwindAction。
25th,Jan,2017
id类型数据
id类型数据则需传入任意由NSObject派生的对象。 但有时也会出现传入一些不是从NSObject继承的属性,因而需要讲这些值用对象封装,或者强转成一个对象。比如,在设置CABasicAnimation的fromValue值时,该值为id类型,支持多种类型的数据传入,那么在传入一些非NSObject继承的属性时则需进行类型转换。
以下是CAPropertyAnimation的一些类型转换:
Type | Object Type | Code Example |
---|---|---|
CGFloat | NSNumber | id obj = @(float); |
CGPoint | NSValue | id obj = [NSValue valueWithCGPoint:point); |
CGSize | NSValue | id obj = [NSValue valueWithCGSize:size); |
CGRect | NSValue | id obj = [NSValue valueWithCGRect:rect); |
CATransform3D | NSValue | id obj = [NSValue valueWithCATransform3D:transform); |
CGImageRef | id | id obj = (__bridge id)imageRef; |
CGColorRef | id | id obj = (__bridge id)colorRef; |
CATransform3D | NSValue | id obj = [NSValue valueWithCATransform3D:transform); |
CGImageRef | id | id obj = (__bridge id)imageRef; |
CGColorRef | id | id obj = (__bridge id)colorRef; |
持续更新,巩固基础(r: 庖丁解牛)
参考资料
叶孤城iOS 开发技巧3
Understanding “extern” keyword in C
iOS 视图控制器转场详解