0%

锁是什么?

锁是一种保证多线程并发执行安全的方式,避免同一时间多个线程同时读取并修改一个值而产生混乱。

例子:火车站多窗口卖票

加锁最重要的就是保证锁是同一把,才能加锁成功。

锁的分类

从大的方向讲有两种锁:互斥锁和自旋锁。

阅读全文 »

tableViewtableHeaderView从xib加载时,使用xib加载的默认尺寸,而不设置frame。当tableView还有个sectionHeader时,tableHeaderView在iOS12上显示正常,但在iOS10、11中,tableHeaderView会覆盖cell,并且sectionHeader会显示在tableView的最上面。而给tableViewHeader视图设置frame时,小屏幕上往往要设置远大于实际需要高度才能正常显示。

阅读全文 »

使用carthage引入RxSwift之后,运行报错:

1
2
3
4
5
6
7
dyld: Library not loaded: @rpath/XCTest.framework/XCTest

Referenced from: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/

Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/libswiftXCTest.dylib

Reason: image not found

解决方法:

阅读全文 »

函数类型

  1. 函数类型定义

    函数类型形式:(参数类型1,参数类型2,…) -> 返回值类型

    函数类型是一种引用类型,类似于函数指针。可以将函数类型应用于任何使用类型的地方:变量、参数、返回值。

    函数类型实例化支持:全局函数、嵌套函数、成员函数(实例方法和静态方法)

  2. 函数的内存模型

    示例说明:

    阅读全文 »

在开发项目中,经常会遇到多输入框页面,如果输入框样式一致或者差异较小,就可以采用tableView来实现。但是在tableView中重用textField会产生两个问题:一个是键盘弹出后textField怎样保持在键盘上方,另一个是textField滑动后会丢失输入数据或者输入数据错乱。其实还有一个附加问题:在使用tableView的页面如何收起键盘?

问题1:键盘弹起后,textField怎样才能保持在键盘上方呢,一般的方式是通过监听键盘弹出和收起的通知来改变tableViewcontentOffset,一个更简单的方式是:

阅读全文 »

  1. datastring互转:

    1
    2
    3
    4
    // data转string
    let string = String(data:data,encoding:.utf8)
    // string转data
    let data = myString.data(using:.utf8)
  2. json数据中的日期格式处理

    阅读全文 »

defer基本理解

在Swift中,defer所声明的block会在当前代码执行退出后被调用。正因为它提供了一种延时调用的方式,所以一般会被用来做资源释放或者销毁,这在某个函数有多个返回出口的时候特别有用。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
func operateOnFile(descriptor: Int32) {
let fileHandle = FileHandle(fileDescriptor: descriptor)
defer { fileHandle.closeFile() }
let data = fileHandle.readDataToEndOfFile()

if /* onlyRead */ { return }

let shouldWrite = /* 是否需要写文件 */
guard shouldWrite else { return }

fileHandle.seekToEndOfFile()
fileHandle.write(someData)
}

需要特别注意的是defer的作用域。

阅读全文 »

__bridge, __bridge_retianed__bridge_transfer用来处理OC对象和CF对象的转换。

转换规则:

  • __bridge:只转换对象类型,不涉及对象所有权的转换(不增加对象引用计数);容易造成悬垂指针。
    • 悬垂指针:指针指向的内存已经被释放;
    • 野指针:没有被正确初始化的指针,指向内存中随机的位置;
  • __bridge_retained:OC对象转换成CF对象,OC对象所有权交给CF对象(CF指针也会持有对象),CF对象需要自己管理内存。
  • __bridge_transfer:CF对象转换成OC对象,将CF对象所有权交给OC对象(CF指针不再持有对象),ARC自动管理内存。

ARC环境下编译器会自动管理OC对象的内存,但是不会自动管理CF对象的内存。

CF对象需要手动释放。

__bridge示例:

1
2
3
4
5
6
7
id obj = [[NSObject alloc] init];

// OC转CF pointer指针不持有对象,不会增加obj的引用计数
void *pointer = (__bridge void *)(obj);

// CF转OC
obj = (__bridge id)(pointer);

__bridge_retained示例:

1
2
3
4
5
6
7
void *pointer = NULL;
{
id obj = [[NSObject alloc] init];
// pointer会引用obj对象
pointer = (__bridge_retained void *)obj;
}
NSLog(@"retain count:%ld", CFGetRetainCount((__bridge CFTypeRef)((__bridge id)pointer))); //retain count:1

__bridge_transfer示例:

1
2
3
4
5
6
7
void *pointer = NULL;
{
id obj = [[NSObject alloc] init];
pointer = (__bridge_retained void *)obj;
}
//pointer持有对象
id object = (__bridge_transfer id)pointer;

  1. 一个视图既要圆角又要阴影效果

    因为设置圆角需要设置maskToBounds为YES,而要设置阴影则maskToBounds为NO,二者不可兼得

    解决方法:

    • A为父视图,B为子视图,设置B与A的约束边距都为0;
    • 设置A的背景色为clearColor,设置A的阴影效果
    • 设置B的背景色为视图实际背景色,设置B的圆角

    另外发现一种更简单的方式:

    需要设置UIView.layer.masksToBounds = NO并且设置UIView.layer.borderWidth = CGFLOAT_MIN即可,某些自定义view在这样设置之后如果仍然无法实现,尝试下设置背景色即可。

  2. convertRect的正确使用

    阅读全文 »

元类型

元类型就是类型的类型。元类型表述为metaType

.Type和.self

Swift中元类型用.Type表示。比如Int.Type就是Int的元类型。

类型和值有着不同的形式,比如说5是个Int类型的值。

.Type是类型的元类型;类型的.self是元类型的值,也就是类型本身。

1
2
let metaTypeValue: Int.Type = Int.self
// metaTypeValue就是Int

元类型在Swift中的应用

在Swift中,获得元类型后可以访问静态变量和静态方法。我们经常使用元类型,比如在tableView中的AnyClass

1
2
3
4
func register(AnyClass?, forCellReuseIdentifier: String)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
//AnyClass
typealias AnyClass = AnyObject.Type

AnyClass就是一个任意类型元类型的别名。

阅读全文 »