使用 brew 安装 openjdk 后,需要关注(使用 brew info openjdk 查看):
1 2 3 4 5 6 7 8 9 10 11 12
For the system Java wrappers to find this JDK, symlink it with sudo ln -sfn /usr/local/opt/openjdk/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk
openjdk is keg-only, which means it was not symlinked into /usr/local, because macOS provides similar software and installing this software in parallel can cause all kinds of trouble.
If you need to have openjdk first in your PATH, run: echo 'export PATH="/usr/local/opt/openjdk/bin:$PATH"' >> ~/.zshrc
For compilers to find openjdk you may need to set: export CPPFLAGS="-I/usr/local/opt/openjdk/include"
同样,安装 openjdk@8 后,需要关注(使用 brew info openjdk@8 查看):
1 2 3 4 5 6 7 8 9 10 11
For the system Java wrappers to find this JDK, symlink it with sudo ln -sfn /usr/local/opt/openjdk@8/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk-8.jdk
openjdk@8 is keg-only, which means it was not symlinked into /usr/local, because this is an alternate version of another formula.
If you need to have openjdk@8 first in your PATH, run: echo 'export PATH="/usr/local/opt/openjdk@8/bin:$PATH"' >> ~/.zshrc
For compilers to find openjdk@8 you may need to set: export CPPFLAGS="-I/usr/local/opt/openjdk@8/include"
qiweipeng@Weipengs-MacBook-Air Developer % pod lib create Hello Cloning `https://github.com/CocoaPods/pod-template.git` into `Hello`. Configuring Hello template. security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
------------------------------
To get you started we need to ask a few questions, this should only take a minute.
If this is your first time we recommend running through with the guide: - https://guides.cocoapods.org/making/using-pod-lib-create.html ( hold cmd and click links to open in a browser. )
What platform do you want to use?? [ iOS / macOS ] > ios What language do you want to use?? [ Swift / ObjC ] > ObjC
Would you like to include a demo application with your library? [ Yes / No ] > yes Which testing frameworks will you use? [ Specta / Kiwi / None ] > None
Would you like to do view based testing? [ Yes / No ] > No
What is your class prefix? > QWP security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain. security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain. security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain. security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain. security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain. security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
[!] Please close any current Xcode sessions and use `Hello.xcworkspace` for this project from now on. Pod installation complete! There is 1 dependency from the Podfile and 1 total pod installed.
Ace! you're ready to go! We will start you off by opening your project in Xcode open 'Hello/Example/Hello.xcworkspace'
To learn more about the template see `https://github.com/CocoaPods/pod-template.git`. To learn more about creating a new pod, see `https://guides.cocoapods.org/making/making-a-cocoapod`.
# # Be sure to run `pod lib lint Hello.podspec' to ensure this is a # valid spec before submitting. # # Any lines starting with a # are optional, but their use is encouraged # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html #
Pod::Spec.new do |s| s.name = 'Hello' s.version = '0.1.0' s.summary = 'A short description of Hello.'
# This description is used to generate tags and improve search results. # * Think: What does it do? Why did you write it? What is the focus? # * Try to keep it short, snappy and to the point. # * Write the description between the DESC delimiters below. # * Finally, don't worry about the indent, CocoaPods strips it!
s.description = <<-DESC TODO: Add long description of the pod here. DESC
for (NSUInteger i = 0; i < outCount; i++) { objc_property_t p = propertyList[i]; NSLog(@"%s", property_getName(p)); NSLog(@"%s", property_getAttributes(p)); }
void playIMP(idself, SEL _cmd) { NSLog(@"Game Start!"); }
void playWithTypeIMP(idself, SEL _cmd, GameType type) { switch (type) { case GameTypeOne: NSLog(@"Game Type One Start!"); break; case GameTypeTwo: NSLog(@"Game Type Two Start!"); break; case GameTypeThree: NSLog(@"Game Type Three Start!"); break; default: break; } }
struct bucket_t { private: // IMP-first is better for arm64e ptrauth and no worse for arm64. // SEL-first is better for armv7* and i386 and x86_64. #if __arm64__ explicit_atomic<uintptr_t> _imp; // 无类型的函数指针,对应具体的函数实现 explicit_atomic<SEL> _sel; // 方法选择器 #else explicit_atomic<SEL> _sel; explicit_atomic<uintptr_t> _imp; #endif // ... };
// Values are the FAST_ flags above. uintptr_t bits; // ...
public:
class_rw_t* data() const { return (class_rw_t *)(bits & FAST_DATA_MASK); } // data,存储可动态改变的部分,内部还包含只读的部分 // ... // Get the class's ro data, even in the presence of concurrent realization. // fixme this isn't really safe without a compiler barrier at least // and probably a memory barrier when realizeClass changes the data field const class_ro_t *safe_ro() { class_rw_t *maybe_rw = data(); if (maybe_rw->flags & RW_REALIZED) { // maybe_rw is rw return maybe_rw->ro; } else { // maybe_rw is actually ro return (class_ro_t *)maybe_rw; } } // 将只读部分暴露出来 // ... };
struct ivar_t { #if __x86_64__ // *offset was originally 64-bit on some x86_64 platforms. // We read and write only 32 bits of it. // Some metadata provides all 64 bits. This is harmless for unsigned // little-endian values. // Some code uses all 64 bits. class_addIvar() over-allocates the // offset for their benefit. #endif int32_t *offset; // 地址的偏移 constchar *name; // 变量名 constchar *type; // 变量类型 // alignment is sometimes -1; use alignment() instead uint32_t alignment_raw; uint32_t size;
Class cls; uintptr_t bits; #if defined(ISA_BITFIELD) struct { ISA_BITFIELD; // defined in isa.h }; #endif };
isa 是一个联合体,在 64 位机器上这个共用体就是 64 位的(32 位下就是 32 位的)。
isa 可能是指针型的,也可能是非指针型的。 指针型就是说这个联合体的内容存储的就是一个指针,比如一个对象的 isa 指针找到对象的类对象。 非指针型的是说,这个联合体中的部分位代表地址,其他位表示一些其他信息。因为 64 位用于存储地址是多余的,只需要部分位已经能满足寻址需要,那么其他剩余的位置就可以存储一些别的。
isa 不总是指向实例所属的类,比如 KVO 就是将被观察对象的 isa 指向一个中间类。确定实例所属的类应该使用 class 方法。
/// Specifies the superclass of an instance. struct objc_super { /// Specifies an instance of a class. __unsafe_unretained _Nonnull id receiver; // 还是调用者本身
/// Specifies the particular superclass of the instance to message. #if !defined(__cplusplus) && !__OBJC2__ /* For compatibility with old objc-runtime.h header */ __unsafe_unretained _Nonnull Class class; #else __unsafe_unretained _Nonnull Class super_class; #endif /* super_class is the first class to search */ };
publicstructHello { var text: String publicinit(withtext: String="Hell, World!") { // there is a bug. self.text = text } publicfuncsayHi() -> String { return text } }
点击加号后,由于已经登陆了 Github,弹出的列表中可以找到之前创建的 Package,当然也可以复制 URL 进行搜索。找到后,会提示我们设置版本规则。其中,默认的 Up to Next Major 的意思是从指定的版本到下个大版本,这样进行小版本更新时,我们可以轻松对 Package 进行更新。再次点击下一步后,会提示选取 Product 以及添加到的 Target,我们都不加修改点击完成。这样,这个 Package 就集成到我们都项目中了。
之后我们在项目中使用一下。
1 2 3 4 5 6 7 8 9 10
// // main.swift // Demo //
import Foundation import Hello
let hello =Hello() print(hello.sayHi()) // Hell, World!