NSTextAttachment

NSTextAttachment: 使用图片创建一个NSAttributedString

UIImage *image = [UIImage imageNamed:@"image_name"];
NSTextAttachment *attachment = [[NSTextAttachment alloc] init];
attachment.image = image;
NSAttributedString *attrStr = [NSAttributedString attributedStringWithAttachment:attachment];
分享到 评论

设置LaunchImage

设置启动页为LaunchImage

1.设置启动页为LaunchImage,方法如下:

  • 1.在Assets.xcassets中新建LaunchImage

    2.在项目TARGETS->General->App Icons and Launch Images中设置 Launch Images Source 为LaunchImage,并将Launch Screen File 设为空(如图)
    LaunchImageSet-01.png

2.在LaunchImage 添加相应启动图片

*    1.如图<br>
LaunchImageSet-02.png
分享到 评论

lantern

lantern 使用中遇到的问题

QQ无法登陆,提示网络错误

解决方法:
在终端运行

sudo killall -9 networkd

然后,重新登陆

注:此方法在 Mac OS X 10.11.5 上测试有效,Windows 操作系统,请参考百度经验-关闭蓝灯/Lantern后无法连接到网络

共享 lantern 到局域网

这里说的局域网是使用无线路由建立的局域网,各设备使用 wifi 功能连接网络。

  1. 使用下面的方式启动 lantern:
lantern -addr=[ip_addr]:[port]
  1. 设置其他设备的代理服务器为 ip_addr,端口号为:port

比如你的电脑的ip地址是192.168.1.2,运行命令lantern -addr=192.168.1.2:8787,然后把你的手机的代理服务器设为192.168.1.2

  1. 打开浏览器,输入 www.google.com ,看看是否能够打开。

附录

获取 ip 地址

Mac 下获取方法:

  1. 系统偏好->网络,在网络状态下即可看到当前连接的热点和自己电脑当前的 ip 地址。

  2. 命令行下,运行命令 ifconfig,查看无线网卡信息,也可以找到 ip 地址。记住网卡的名字,(一般格式为en0,en1…),以 en0 为例,以后可直接输入ifconfig en0 来查看 ip 地址。

  3. ipconfig getifaddr en0 (注:en0 是你电脑上正在使用的无线网卡的名字,也可能是en1)

手机上设置代理

iPhone 上设置代理方法:

  1. 设置 -> Wi-Fi,进入到 wifi 页面,在当前连接的 wifi 的右侧有一个蓝色圆圈,中间有一个感叹号。
  2. 点击这个按钮,进入到当前连接 wifi 的详情页。在这个页面的最底部看到 ”HTTP 代理“,默认是“关闭”的
  3. 选择“手动”,在“服务器”一行,输入或获取到的电脑 ip,在“端口”一行,输入启动 lantern 使用的端口号。
  4. 返回

注意:不需要翻墙的时候,切记把代理关闭,否则无法上网。

分享到 评论

fucking blocks syntax

声明:内容来自http://fuckingblocksyntax.com/

How Do I Declare A Block in Objective-C?

As a local variable:

returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};

As a property:

@property (nonatomic, copy, nullability) returnType (^blockName)(parameterTypes);

As a method parameter:

- (void)someMethodThatTakesABlock:(returnType (^nullability)(parameterTypes))blockName;

As an argument to a method call:

[someObject someMethodThatTakesABlock:^returnType (parameters) {...}];

As a typedef:

typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
分享到 评论

clang命令

Wiki

Clang /ˈklæŋ/ is a compiler front end for the programming languages C, C++, Objective-C, Objective-C++, OpenMP, OpenCL, and CUDA. It uses LLVM as its back end and has been part of the LLVM release cycle since LLVM 2.6.

It is designed to be able to replace the full GNU Compiler Collection (GCC). Its contributors include Apple, Microsoft, Google, ARM, Sony, Intel and Advanced Micro Devices (AMD). It is open-source software, with source code released under the University of Illinois/NCSA License, a permissive free software licence.

https://en.wikipedia.org/wiki/Clang

LLVM

LLVMLow Level Virtual Machine (底层虚拟机)的简称,这个库提供了与编译器相关的支持,能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。可以作为多种语言编译器的后台来使用。

clang -rewrite-objc

clang -rewrite-objc 的作用是把 oc 代码转写成 c/c++ 代码,推测 OC 底层的实现原理。

使用方法

clang -rewrite-objc <Objective-C source file>

比如,在 OC 中,方法调用又称为消息发送,但消息发送是怎么实现的呢?

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Person *p = [Person new];
[p foo];
}

在终端输入

clang -rewrite-objc ViewController.m

在生成的 ViewController.cpp 文件中,可以找到 ViewDidLoad 方法改写后的实现:

static void _I_ViewController_viewDidLoad(ViewController * self, SEL _cmd) {
((void (*)(__rw_objc_super *, SEL))(void *)objc_msgSendSuper)((__rw_objc_super){(id)self, (id)class_getSuperclass(objc_getClass("ViewController"))}, sel_registerName("viewDidLoad"));
Person *p = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("new"));
((void (*)(id, SEL))(void *)objc_msgSend)((id)p, sel_registerName("foo"));
}

也就是说 [p foo] 在动态编译的时候,会被转意为: objc_msgSend(p, sel_registerName("foo"));

指定SDK

OC 代码转写成 C/C++ 代码时,在模拟器和真机上,有时候是有区别的。如果需要指定 SDK ,那么要结合xcrun命令。

真机:

xcrun -sdk iphoneos[ver] clang -rewrite-objc <inputs>

模拟器:

xcrun -sdk iphonesimulator[ver] clang -rewrite-objc <inputs>

可通过 xcodebuild -showsdks 来查看机器上的 SDK

OS X SDKs:
OS X 10.11 -sdk macosx10.11
iOS SDKs:
iOS 9.3 -sdk iphoneos9.3
iOS Simulator SDKs:
Simulator - iOS 9.3 -sdk iphonesimulator9.3
tvOS SDKs:
tvOS 9.2 -sdk appletvos9.2
tvOS Simulator SDKs:
Simulator - tvOS 9.2 -sdk appletvsimulator9.2
watchOS SDKs:
watchOS 2.2 -sdk watchos2.2
watchOS Simulator SDKs:
Simulator - watchOS 2.2 -sdk watchsimulator2.2

指定 framework

如果使用了iOS frameworks,(如UIKit) 或者 第三方 SDK (如听云),执行clang -rewrite-objc的时候会提示错误:

ViewController.h:9:9: fatal error: 'UIKit/UIKit.h' file not found
#import <UIKit/UIKit.h>
^
1 error generated.

这是因为没有引入 framework,clang 不知道去哪里找,需要用 -F 选项指定 要引入的 framework。

clang -rewrite-objc -F UIKit <inputs>

如果指定了 sdk,则不需要指定 iOS 内部 frameworks

```

之前在读 Apple 开源的 runtime 源码的时候,经常使用这个命令,就起了个简短的别名,方便使用:

  1. 在~/.bashrc 或者 ~/.zshrc(for zsh 用户)中添加一行 alias deoc="xcrun -sdk iphonesimulator9.3 clang -rewrite-objc"。(请先使用xcodebuild -showsdks` 查看自己电脑上的 sdk 做相应修改)
  2. 保存,退出;打开一个新窗口,或者在当前窗口运行 source ~/.bashrc(for bash users) 或者 source ~/.zshrc (for zsh users)
  3. 现在开始,使用 deoc 来代替 xcrun -sdk iphonesimulator9.3 clang -rewrite-objc ,后面接 OC 源文件 (和 -F framework,如果需要引入第三方 sdk)。

关于clang的更多使用方法,请参考:

  1. objc 中国-编译器
  2. man clang

Refrences:

  1. clang -rewrite-objc的使用点滴
分享到 评论

Core Data

Core Data

Core Data Stack

Managed Object Model - It describs the schema that you use in the app. In Xcode, the Managed Object Model is defined in a file with the extension .xcdatamodeld. You can use the visual editor to define the entities and their attributes, as well as, relationships.

Persistant Store Coordinator - SQLite is the default persistant store in iOS. However Core Data allows developers to setup multiple stores containing different entities. The Persistant Store Coordinator is the party responsible to manage different persistant object stores and save th objects to the stores. Forget about it you don’t understand what it is. You’ll not interact with Persistant Store Coordinator directly when using Core Data.

Managed Object Context - Think of it as a “scratch pad” containing objects that interacts with data in persistent store. Its job is to manage objects created and returned using Core Data. Among the components in the Core Data Stack, the Managed Object Context is the one you’ll work with for most of the time. In general, whenever you need to fetch and save objects in persistent store, the context is the first component you’ll talk to.

The below illustration can probably give you a better idea about the Core Data Stack

分享到 评论

将命令行输出放在剪切板上

为什么要这么做?

  • 直接把命令的输出(比如grep/awk/sed/find或是你的程序输出结果)放到剪切板上,这么就可以在IM中CTRL + V粘贴后发出去。
  • 避免操作的繁琐和跳跃:把结果输出到文件、用文本编辑器打开文件、选中文本、CTRL + C。
  • 通过命令将文件内容拷贝到剪切板,以避免拷贝错误、操作的跳跃(跳到文件编辑器)

Windows下

使用系统自带的clip命令。

位于C:\Windows\system32\clip.exe。

示例:

$ echo Hello | clip #将字符串Hello放入Windows剪贴板
$ dir | clip #将dir命令的输出放入Windows剪切板
$ clip < README.TXT #将README.TXT的文本放入Windows剪切板
$ echo | clip # 将一个空行放入Windows剪切板,即清空Windows剪切板

Linux下

使用xsel命令。

参见笔记:How do I pipe terminal standard output (stdout) to the clipboard?

示例:

$ cat README.TXT | xsel #将输出放在剪切板
$ cat README.TXT | xsel -b # 如有问题,可以试试-b选项
$ xsel < README.TXT # 将readme.txt的文本放入剪贴板
$ xsel -c # 清空剪贴板

Mac下

使用 pbcopy 命令。 # 对应有个pbpaste命令。

示例:

$ echo ‘Hello World!’ | pbcopy #将字符串“Hello World!”放入剪切板
$ pbpaste #将剪切板中内容输出到终端
分享到 评论