0%

  1. keykeypath匹配

    addObserver: forKeyPath: options: context:的“keypath”和setValue: forKey的“key”或setValue: forKeyPath:的“keyPath”或setter方法对应的属性名保持一致,observeValueForKeyPath: ofObject: change: context: 方法才会被触发。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //self.student.name
    [self.student addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];

    [self.student setName:@"baylee"];//student有"name"属性或成员变量
    [self.student setValue:@"baylee" forKey:@"name"];

    //self.student有teacher属性,teacher有个className属性
    [self.student addObserver:self forKeyPath:@"teacher.className" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];

    self.student.teacher.className = @"english";
    [self.student setValue:@"english" forKeyPath:@"teacher.className"];
    阅读全文 »

在iOS开发中,为保证单例在整个程序运行中只被初始化一次,单线程的时候,通过静态变量可以实现;但是多线程的出现,使得在极端条件下,单例也可能返回了不同的对象。如在单例初始化完成前,多个进程同时访问单例,那么这些进程可能都获得了不同的单例对象。苹果提供了 dispatch_once(dispatch_once_t *predicate,dispatch_block_t block);函数来避免这个问题。在实现单例类的时候,我们通常会下面的代码来初始化单例:

阅读全文 »

在多线程操作中,为了保证多线程安全,可以使用NSLock类使多个线程间互斥地使用全局变量等共享资源。NSLock类的实例就是可以调整多线程行为的信号量或互斥型信号量。在Cocoa环境中叫锁。

加锁和解锁的方法都声明在NSLocking协议中。

阅读全文 »

  • DPI是每英寸的点数,可以简单理解为点的密度。

  • PPI是每英寸的像素数,可以简单理解为像素密度。

点和像素有区别吗?很多时候,一个点 = 一个像素。但是,并不尽然,如iPhone的视网膜屏幕,它一个点包含了四个像素,大大提高了显示清晰度。

阅读全文 »

自定义值类型实现Equatable协议,可以测试相等性;实现Comparable,可以测试可比性。

Equatable协议

Equatable协议指出,符合这个协议的类型应该有一个静态方法==;一旦一个类型通过实现自己的==符合了Equatable,也就有了!=函数。

1
2
3
4
5
6
7
8
9
10
11
12
struct Point:Equatable{
let x: Int
let y: Int
static func ==(point1: Point, point2: Point) -> Bool{
return (point1.x == point2.x) && (point1.y == point2.y)
}
}

let a = Point(x:3, y:4)
let b = Point(x:12, y:5)
let abEqual = (a==b)
let abNotEqual = (a!=b)

==声明为静态方法,但==的调用并不是在Point类型上,这时因为==这样的运算符在Swift中是定义在全局层面的。==在Swift标准库中的定义:

阅读全文 »

某个请求参数为数组类型时,不能直接将array作为请求参数的键值,需要将数组转成jsonString再进行请求:

1
2
3
4
5
6
7
8
9
if (imgs.count) {
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:imgs
options:kNilOptions
error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
[dic setValue:jsonString forKey:@"imageList"];
}
阅读全文 »

逃逸:一个函数的闭包可能会在该函数返回后被调用,闭包逃脱出了接收它作为参数的函数的作用域。

非逃逸闭包是不可能产生循环强引用的闭包,不需要显式引用self,所以可以隐式地调用self的属性和方法。

以函数参数形式声明的闭包默认是非逃逸的;其他场景中的闭包是逃逸的。

如果把闭包保存到属性中,意味着可以在函数返回后调用它,也就是说闭包会逃脱出函数的作用域:

阅读全文 »

协议扩展解决的问题

在OOP(object-oriented programming,面向对象编程)中,过深的继承层次很容易让代码充满难以理解的类。改用泛型和协议,即使使用值类型,协议也能解决OOP中继承能解决的问题。

协议扩展要求

使用关键字extension

可以添加有实现的属性(计算属性)和方法,但不会增加协议的需求;

不能添加存储属性;

协议扩展内的实现只能访问其他肯定存在的属性和方法;

协议扩展的where子句

where子句可以为协议扩展增加一些限制,形式:

1
2
3
extension ProtocolName where condition {
//扩展内容
}

用协议扩展提供默认实现

可以利用协议扩展提供协议自身需求的默认实现。当协议为部分或所有属性或方法提供默认实现时,符合这个协议的类型就不需要进行实现。但是如果默认实现不合适,符合协议的类型也可以选择自己实现。

枚举类型的知识点:基本语法、关联值、原始值、枚举类型和方法、递归枚举

枚举语法

要点
  • 枚举类型名大写开头
  • 多个成员值可以出现在同一行,用逗号隔开
    阅读全文 »

cell自适应的怨念

iOS7中估算cell 高度的方法:estimatedRowHeight

1
2
3
4
5
6
7
self.tableView.estimatedRowHeight = 88;

// or

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
// return xxx
}

估算高度出现的问题:

阅读全文 »