get请求和post请求
提交用户的隐私数据一定要使用POST请求,相对于POST请求而言,GET请求的所有参数都直接暴露在URL中,请求的URL一般都会记录在服务器的访问日志中,而服务器的访问日志是黑客攻击的主要对象之一。
这里所说的用户隐私数据一般来说是指登录密码,银行账号等等。
URL不允许写中文怎么办
可以通过转码的方式进行解决
urlStr= [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
如何判断一个实例是否属于特定的子类型
可以使用类型操作符(is)来进行判断,如果实例属于那个子类型,类型操作符返回true,反则的话返回false
let str = "abcdef"
if str is String
{
print("string")
}
else
{
print("noString")
}
遍历所有的cell
for(NSIndexPath *cellIndex in [self.tableView indexPathsForVisibleRows])
TableViewCell *otherCell = [self.tableView cellForRowAtIndexPath:cellIndex];
栈和堆的理解
管理方式:
对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。
申请大小:
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
碎片问题:
对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出
分配方式:
堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
分配效率:
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的。
简而言之,操作系统使用stack 段中的指针值访问heap 段中的对象。如果stack 对象的指针没有了,则heap 中的对象就不能访问。这也是内存泄露的原因。
assign得到的b是栈和堆都跟a相同
retain得到的b是在栈上重新开了一个地址,和a共同管理在堆上的内容
copy得到的b是栈和堆都开辟新的地址。
guard的使用
//检查身份证,如果身份证没带,则不能进入考场
guard let id = person["id"]else
{
print("没有身份证,不能进入考场")
return
}
//身份证和准考证齐全,方可进入考场
print("您的身份证号为:\(id),准考证号为:\(examNumber)。请进入考场!")
这里值得注意的是,id和examNumber可以在guard语句之外使用,也就是说当guard对其表达式进行验证后,id和examNumber可在整个方法的作用域中使用,并且是解包后的。
tableview左侧空白处理
在ios7中,UITableViewCell左侧会有默认15像素的空白。这时候,设置setSeparatorInset:UIEdgeInsetsZero 能将空白去掉。
但是在ios8中,设置setSeparatorInset:UIEdgeInsetsZero 已经不起作用了。下面是解决办法
首先在viewDidLoad方法加入以下代码:
if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
}
if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
然后在UITableView的代理方法中加入以下代码
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
UIView的clipsToBounds和CALayer的的masksToBounds之间的关系??
clipsToBounds
是指视图上的子视图,如果超出父视图的部分就截取掉,
masksToBounds
却是指视图的图层上的子图层,如果超出父图层的部分就截取掉
图像的拉伸方法
- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:
关于GCD的一些常用方法
// 创建目标队列
let workingQueue = dispatch_queue_create("my_queue", nil)
// 派发到刚创建的队列中,GCD 会负责进行线程调度
dispatch_async(workingQueue) {
// 在 workingQueue 中异步进行
print("努力工作")
NSThread.sleepForTimeInterval(2) // 模拟两秒的执行时间
dispatch_async(dispatch_get_main_queue()) {
// 返回到主线程更新 UI
print("结束工作,更新 UI")
}
}
多线程单例
dispatch_once_t必须是全局或static变量
//静态变量,保证只有一份实例,才能确保只执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//单例代码
});
关于时间的一些宏
#define NSEC_PER_SEC 1000000000ull
#define USEC_PER_SEC 1000000ull
#define NSEC_PER_USEC 1000ull
NSEC:纳秒。
USEC:微秒。
SEC:秒
PER:每
1 NSEC_PER_SEC,每秒有多少纳秒。
2 USEC_PER_SEC,每秒有多少毫秒。(注意是指在纳秒的基础上)
3 NSEC_PER_USEC,每毫秒有多少纳秒。
mac使用技巧
在Mac下想知道某个目录下各个文件和子目录各占多少空间,不需要一个一个去查看。打开终端,在该目录下输入:du -sh *,结果是啥,你们试试就知道了
很多刚开始使用Mac的用户,一般都知道Spotlight功能,快速定位和检索文件。事实上用这个功能还可以快速打开程序。通过ctrl+space呼出,输入通讯或cont,都可以找到通讯录这个程序,回车即可打开
shift+command+3:全屏幕截图;shift+command+4:通过鼠标选取截图。
1、Mac的原生输入法
我在Mac下曾经使用过很多输入法,包括FIT、搜狗、QQ、QIM等,这是因为Mac的原生输入法太不给力了。但是OS X升级到Mountain Lion之后,原生输入法有了很大的改进,慢慢的,现在最常用的变成了原生输入法,今天就为大家介绍一些Mac输入法的操作技巧
中英文混合输入,输入中文的时候,打开caps lock键,可以直接输入英文,关掉又切换回中文
选词,通过-+号可以切换字或词,通过[]可以展开候选词列表并进行切换
打开输入法偏好设置,可以设置自动校正模糊音
用 ' 可以进行手动分词,比如fang'an(方案)
适用shift + 6可以输入表情符号,比如(☆_☆)凸-凸
2、Safari的标签
当你想在新的标签页打开网页时,只需要按住command键,点击链接即可
使用 Multi-Touch 手势在标签页中切换。在触控板上,双指开合即可显示你打开的标签页。在标签视图中,双指轻扫可浏览不同标签页
通过shift+command+左右方向键,可以快速在Safari中打开的标签中进行切换。
设置全局打印
#ifdef DEBUG
#define DMLog(...)NSLog(@"%s%@",__PRETTY_FUNCTION__,[NSString stringWithFormat:__VA_ARGS__])
#else
#define DMLog(...) do { } while (0)
#endif
让Xcode的控制台支持LLDB类型的打印
- touch ~/.lldbinit
- echo display @import UIKit >> ~/.lldbinit
- echo target stop-hook add -o "target stop-hook disable" >> ~/.lldbinit
删除
其实很简答, 看第一条命令touch ~/.lldbinit 就是在根目录下创建了一个隐藏文件.lldbinit , 然后删除这个文件就搞定啦. 打开终端然后, 在终端输入 :
rm ~/.lldbinit 命令即可
让程序在后台长久运行的示例代码:
// AppDelegate.h 文件
@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;
// AppDelegate.m 文件
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[self beingBackgroundUpdateTask];
// 在这里加上你需要长久运行的代码
[self endBackgroundUpdateTask];
}
- (void)beingBackgroundUpdateTask
{
self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundUpdateTask];
}];
}
- (void)endBackgroundUpdateTask
{
[[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}
网友评论
TableViewCell *otherCell = [self.tableView cellForRowAtIndexPath:cellIndex];
这个只能遍历屏幕上可见的cell 的indexPath 要想获取所有的indexPath应该这样吧
- (NSArray *)cellsForTableView:(UITableView *)tableView {
NSInteger sections = tableView.numberOfSections;
NSMutableArray *cells = [[NSMutableArray alloc] init];
for (int section = 0; section < sections; section++) {
NSInteger rows = [tableView numberOfRowsInSection:section];
for (int row = 0; row < rows; row++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
[cells addObject:indexPath];
}
}
return cells;
}
在通过遍历存放 indexPath的数组 获取所有的Cell