RuntimeSummary - 一个集合了常用 Runtime 使用方法的 Playground

RuntimeSummary

https://github.com/Tuccuay/RuntimeSummary

RuntimeSummary

一个集合了常用 Objective-C Runtime 使用方法的 Playground

目录

如何使用这个 Playground

Screenshot

先选择 Scheme,然后 Run!

消息机制介绍 / Messaging

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 创建一个对象
// Cat *harlan = [[Cat alloc] init];

// 使用 Runtime 创建一个对象
// 根据类名获取到类
Class catClass = objc_getClass("Cat");

// 同过类创建实例对象
// 如果这里报错,请将 Build Setting -> Enable Strict Checking of objc_msgSend Calls 改为 NO
Cat *harlan = objc_msgSend(catClass, @selector(alloc));

// 初始化对象
// harlan = [harlan init];

// 通过 Runtime 初始化对象
harlan = objc_msgSend(harlan, @selector(init));

// 调用对象方法
// [harlan eat];

// 通过 Runtime 调用对象方法
// 调用的这个方法没有声明只有实现所以这里会有警告
// 但是发送消息的时候会从方法列表里寻找方法
// 所以这个能够成功执行
objc_msgSend(harlan, @selector(eat));

// 输出: 2016-04-21 21:10:20.733 Messaging[20696:1825249] burbur~

// 当然,objc_msgSend 可以传递参数
Cat *alex = objc_msgSend(objc_msgSend(objc_getClass("Cat"), sel_registerName("alloc")), sel_registerName("init"));
objc_msgSend(alex, @selector(run:), 10);

阅读全文

在 iOS 上开始创建你的虚拟现实应用

在 iOS 上开始创建你的虚拟现实应用
原文链接 : Getting Started | Cardboard | Google Developers
译文链接 : 在 iOS 上开始创建你的虚拟现实应用

以前 Cardboard 也是支持在 iOS 上使用的,依靠 Unity 来实现,所以你需要用 C# 来编写 iOS app(听起来很奇怪对不对?) 而今天在 GDG China 看见 全新 VR 视图:让你的应用和网站嵌入沉浸式内容 当然迫不及待的想尝试一下,于是翻译了最新的文档,大家一起来体验一下在 iOS 上实现虚拟现实的新方式吧。

Cardboard 是 Google 一款能够很方便让你的手机变身 VR 设备的产品,如果你还没有拥有它,可以去某宝买一个 ;)

这个 Cardboard SDK 可以让你很方便的控制音频的空间感(例如左右声道),也可以控制响度,所以你可以让一段对话在一个小飞船中或者一个很大的地下洞穴中表现得很不一样。

在这个示例程序中我们完成了一个寻宝游戏,他演示了 Cardboard 的核心功能。玩家将会在一个虚拟的世界中寻找宝物。你将会学习如何使用光照、空间运动和着色等基本功能如果玩家看见了他要找的东西,将会触发空间音效和视差效果。

基本要求

为了能够运行这个示例程序,你至少需要满足以下条件:

  • Xcode 7.1 或更高版本
  • CocoaPods, 访问 CocoaPods 来安装。
  • 一部运行 iOS 7.0 或更高版本的 iPhone。

阅读全文

<Error>: CGContextDrawImage: invalid context 0x0.

1
2
Feb 26 13:46:50  ProjectName[48427] <Error>: CGContextDrawImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Feb 26 13:46:50 ProjectName[48427] <Error>: CGBitmapContextCreateImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.

Google 半天毫无头绪,少量的结果将问题指向 iOS9 的适配,以及部分引用 Apple Developer Fourm 的问题说明这是 Xcode 的一个 bug。

然而…踩坑什么的最讨厌了,肯定不是,我再看看…

Interface Builder - error cell

在某个 .xib 里面发现本该是 UICollectionViewCell 被我拖了一个 UIView 进去,遂换成 UICollectionViewCell 再试,错误依旧…

阅读全文

Pro Git 2 阅读笔记

原书地址: http://git-scm.com/book/zh/v2

初始化一个 repo

1
2
3
4
git init // 将在目录下创建 .git
git add . // 添加目录下所有文件到 git 暂存区(Staging Area)
// 不要忘记 LICENSE 和 README.md
git commit -m "init a project" // 提交到本地 repo

克隆一个仓库 git clone

1
2
git clone https://example.com/username/repo
git clone https://example.com/username/repo rename // 将以 "rename" 存储

查看当前状态 git status

1
git status
  • Untracked 未跟踪的数据:文件在文件夹中,但不在仓库中
    • 是新增文件,将显示 new file: file.name 使用 git add 来添加它
    • 已经从 repo 中 git remove
  • Unmodified 未更改:一起都和看上去的一样
  • Modified 已更改:文件发生了变化
    • 将显示 modified: file.name 需要 git add 来暂存更改
  • Staged 已暂存:改动已经存储到暂存区

阅读全文

计蒜客 CS113 Python 程序设计

A+B+C 问题

这是一个非常简单的题目,意在考察你编程的基础能力。千万别想难了哦。输入为三行,每行一个整数,分别为 A、B、C(数据范围均在 -40 ~ 40 之间)。输出为一行,为“A+B+C”的计算结果。

1
2
3
4
5
input_list = raw_input().split(' ')
sum = 0
for input_number in input_list:
sum = sum+int(i)
print sum

批量替换字符串

在网络编程中,如果 URL 中含有特殊字符,如空格、# 等,服务器将无法识别导致无法获得正确的参数值,我们需要将这些特殊字符转换成服务器可以识别的字符,例如将空格转换成 %20。给定一个字符串,将其中的空格转换成 %20
输入一个原始字符串,例如 hello world
输出转换后的字符串,例如 hello%20world

1
2
3
source_str = raw_input()
source_str = source_str.replace(' ', '%20')
print source_str

阅读全文

多线程:pthread、NSThread、GCD 和 NSOperation

在 iOS 开发中,可以通过以下四种方法创建子线程:

pthread

pthread 是来自 Clang 中的方法,使用前需要手动 #import <pthread.h>

1
2
3
4
5
6
7
8
9
10
11
/*
* <#pthread_t *restrict#> : 要在哪一个线程对象中执行(Thread Object 的地址)
* <#const pthread_attr_t *restrict#> : 要给Thread Object 的属性
* <#void *(*)(void *)#> : 要执行的函数(指向函数的指针)
* <#void *restrict#> : 要传入的参数
*/
pthread_create(<#pthread_t *restrict#>, <#const pthread_attr_t *restrict#>, <#void *(*)(void *)#>, <#void *restrict#>)

pthread_t thread; // 声明一个线程对象(Thread Object)
// 在 "thread" 线程对象中执行名为 "runInChildThread" 的函数,线程名为 "anChildThread"
pthread_create(&thread, NULL, runInChildThread, (__bridge void *)(@"anChildThread"));

NSThread

直接创建一个子线程 (alloc init)
1
convenience init(target target: AnyObject, selector selector: Selector, object argument: AnyObject?)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument

/*
<#(nonnull id)#> : 目标对象
<#(nonnull SEL)#> : @selector(),需要调用的方法
<#(nullable id)#> : 前面方法要接收的参数(对象)
*/
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument
NSThread *thread = [[NSThread alloc] initWithTarget:<#(nonnull id)#> selector:<#(nonnull SEL)#> object:<#(nullable id)#>];
thread.name = @"some name"; // operational
thread.threadPriority = 1.0 // operational 1.0 为最高优先级
// #warning: thread 在执行完成后将会死亡
// 即使有 strong 指向导致没有被释放,也不能再次 + (void)start;
// 否则会 carsh
[thread start];
// 休眠(阻塞)线程,直到 aDate 再继续执行
+ (void)sleepUntilDate:(NSDate *)aDate
// 休眠(阻塞)线程,直到 ti 秒之后再继续执行
+ (void)sleepForTimeInterval:(NSTimeInterval)ti
// 退出线程
+ (void)exit
分离出一条子线程
1
class func detachNewThreadSelector(_ selector: Selector, toTarget target: AnyObject, withObject argument: AnyObject?)
1
2
3
4
5
6
7
8
+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument

/*
* <#(nonnull SEL)#> : 要执行的方法
* <#(nonnull id)#> : 执行方法目标对象
* <#(nullable id)#> : 要传入的参数
*/
[NSThread detachNewThreadSelector:<#(nonnull SEL)#> toTarget:<#(nonnull id)#> withObject:<#(nullable id)#>];
创建一条后台线程
1
func performSelectorInBackground(_ aSelector: Selector, withObject arg: AnyObject?)

阅读全文

Launch a iOS app / 应用启动原理

  1. 首先将会启动 main.m
  2. 在其中创建 UIApplication 对象;
  3. 并为其设置代理。

    1
    2
    3
    4
    5
    6
    7
    8
    #import <UIKit/UIKit.h>
    #import "AppDelegate.h"

    int main(int argc, char * argv[]) {
    @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
    }

    argc, argv, nil, NSStringFromClass([AppDelegate class]) 中:

    • nilUIApplication 类或其子类的名称,当传入 nil 时视为传入 @"UIApplication"
    • NSStringFormClass([AppDelegate class]) 为获取 AppDelegate 的类名;
  4. 开始一个主运行循环 (RunLoop),保证 app 运行期间不会退出
  5. 加载 info.plist,如果其中指定有 Main storyboard file base name 则加载对应的 StoryBoard:
    创建⼀一个窗⼝,加载 MainStoryBoard,初始化⼀个控制器,把初始化出来的控制器设置为窗⼝的根控制器.让窗口显示到屏幕上
  6. 如果其中没有指定 Main storyboard file base name (recommened):

    阅读全文

Objective-C/OC Syntactic sugar/语法糖

Dot syntax / 点语法

快速使用 setter / getter 赋值/获取值

一般情况:

1
2
3
4
getter:    [anObject setKey:Value];    // 给 anObject 发送消息 setKey: ,传入 Value
// 即使用 anObject 的类方法 - (returnValueType)getKey;
setter: [anObject key]; // 给 anObject 发送消息 key
// 即使用 anObject 的类方法 -(void)key:(keyValueType)key;

使用点语法:anObject.key
1
2
setter:    key.value = aNumber;
getter: something = key;

Object Literals

快速赋值替代初始化赋值、构造方法 / 工厂方法 / Factory method pattern

NSString / NSMutableString

1
2
3
4
5
6
7
8
+ (instancetype)string;    // 生成空的字符串
NSString *string = [NSString string];
+ (instancetype)stringWithString; // 工厂方法生成字符串
NSString *strWithStr = [NSString stringWithString:@"There is a string"];
+ (instancetype)initWithString:(NSString *)aString; // 构造方法初始化字符串
NSString *intWithStr = [[NSString alloc] initWithString:@"Init with string"];

NSString *sugarString = @"Is Awesome!"; // 语法糖!

阅读全文

FATA[0000]Are you trying to connect to a TLS-enabled daemon without TLS

1
FATA[0000] Post http:///var/run/docker.sock/v1.17/containers/create: dial unix /var/run/docker.sock: no such file or directory. Are you trying to connect to a TLS-enabled daemon without TLS

Are you trying to connect to a TLS-enabled daemon without TLS
从 Vagrant 的深坑掉入了 Docker 的深坑,OS X 使用 Boot2Docker 来使用 Docker,直接从官网下载后安装出现了上面的错误,但是Google之发现几乎没有人遇上过…

阅读全文