coding with objc & swift

什么时候使用updateConstraints

| Comments

UIView中的 updateConstraints 方法一直是一个纠结的存在。按照苹果官方文档中给出的建议:

Custom views that set up constraints themselves should do so by overriding this method. When your custom view notes that a change has been made to the view that invalidates one of its constraints, it should immediately remove that constraint, and then call setNeedsUpdateConstraints to note that constraints need to be updated. Before layout is performed, your implementation of updateConstraints will be invoked, allowing you to verify that all necessary constraints for your content are in place at a time when your custom view’s properties are not changing.

当视图的改变使得某个约束无效时,应当把该约束移除,并调用 setNeedsUpdateConstraints 以标记视图需要更新约束,然后在 updateConstraints 中更新约束。

然而,实际上却并不那么好用:

一起来构建@synchronized

| Comments

本期的「一起来构建」,我将探索实现Objective-C的@synchronized语法。我会用Swfit来实现它,Objective-C版本的实现并没有什么差别。

回顾

@synchronized是Objective-C中的一种控制构造(control construct)。 它需要一个对象的指针作为参数,然后后面接着一个代码块。对象指针作为锁,任何时候只允许一个线程访问该代码块。

这是多线程编程使用锁的一个简单方法。例如,你可以用一个NSLock来保护对一个NSMutableArray的访问:

1
2
3
4
5
6
NSMutableArray *array;
NSLock *arrayLock;

[arrayLock lock];
[array addObject:obj];
[arrayLock unlock];

或者你可以使用@synchronized使用数组本身作为锁:

1
2
3
@synchronized(array) {
	[array addObject:obj];
}

我个人更喜欢使用一个明确的锁,既说得清楚是怎么回事,也因为一些原因@synchronized执行效率不是很好,我们接下来会看到。但是,它很方便,并且构建一个@synchronized也很有意思。

Content Compression Resistance和Content Hugging

| Comments

Auto Layout中,Content Compression Resistance 和 Content Hugging 这两个概念,从字面上很难理解它们真正的意思和用途,在苹果官方文档中相关描述也比较少。中文世界没有与之对应的特别形象的中文翻译。objc中国上,将其分别翻译为内容压缩阻力和内容吸附性,这可能一定程度上更加深了理解的难度。

这两个概念,一直是一知半解,最近搜索和查看了许多文章和资料才彻底搞清楚了它们的作用,所以在此整理一下。

一起来构建Dispatch Groups

| Comments

Dispatch Group是一个方便的用于同步多任务的工具,一个匿名的读者建议将它作为今天的「一起来构建」的主题。

回顾

Dispatch group提供了4种基本的操作:

  1. 进入(Enter),表明任务开始。
  2. 退出(Exit),表明任务完成。
  3. 通知(Notify),用于在所有任务完成后调用一个block。
  4. 等待(Wait),有点像notify,但是是同步的。

你可以用它来分拆一堆并行操作,等待它们完成:

1
2
3
4
5
6
7
8
9
dispatch_group_t group = dispatch_group_create();
for(int i = 0; i < 100; i++)
{
   dispatch_group_enter(group);
   DoAsyncWorkWithCompletionBlock(^{
       dispatch_group_leave(group);
   });
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

停止重写setter方法,你应该用KVO

| Comments

本文译自:Stop overriding setters and just use KVO

KVO(Key-Value-Observing)是一个充满分歧的API,是的,至少可以这么说。尽管它有(文档记录的)缺陷,但在想知道某个属性值是否变化的时候,我个人更倾向于使用它。但是我和许多开发者交流过(包括我在Tumblr的iOS开发同事),大多数人都更倾向于采用重写setter的方法。这里有一种情况,我认为KVO会比重写setter的方法稍微好一点。

假设你有一个自定义的视图控制器的子类并带有一个属性。修改这个属性的值会导致视图控制器的视图或子视图发生一些变化。Tumblr的代码库中正好有一个这样的例子:

1
2
3
4
5
6
7
8
- (void)setContainerScrollable:(BOOL)containerScrollable {
    if (_containerScrollable != containerScrollable) {
        _containerScrollable = containerScrollable;

        self.container.scrollEnabled = containerScrollable;
        self.tableView.scrollEnabled = !containerScrollable;
    }
}