Block - 本质认识,变量捕获,类型
基本认识
block本质上也是一个OC对象,它内部也有个isa指针
block是封装了函数调用以及函数调用环境的OC对象
以下是一个block:123456int age = 20; void (^block)(int, int) = ^(int a , int b){ NSLog(@"this is a block! -- %d", age);};block()
底层数据结构1234567891011121314151617struct __main_block_desc_0 { size_t reserved; size_t Block_size;};struct __block_impl { void *isa; int Flags; int Reserved; void *FuncPtr;};struct __main_block_impl_0 { struct __block_impl impl; struct __ ...
Category - 关联对象
关联对象
默认情况下,因为分类底层结构的限制,不能添加==成员变量==到分类中,但可以通过==关联对象==来间接实现
关联对象提供了以下API:
添加关联对象
void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)
获得关联对象
id objc_getAssociatedObject(id object, const void * key)
移除所有的关联对象
void objc_removeAssociatedObjects(id object)
key的常见用法123456789101112131415static void *MyKey = &MyKey;objc_setAssociatedObject(obj, MyKey, value, OBJC_ASSOCIATION_RETAIN_NONATO ...
Category - initialize
initialized
+initialized方法会在类第一次接收到消息时调用
调用顺序
先调用父类的+initialize,再调用子类的+initialize
先初始化父类,再初始化子类,每个类只会初始化1次
+initialize和+load的很大区别是,+initialize是通过objc_msgSend进行调用的,所以有以下特点
如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
如果分类实现了+initialize,就覆盖类本身的+initialize调用
objc4源码解读
objc-msg-arm64.s,汇编级别的源码
objc_msgSend,消息发送汇编源码
objc-runtime-new.mm
class_getInstanceMethod
lookUpImpOrNil
lookUpImpOrForward
_class_initialize
callInitialize
objc_msgSend(cls, SEL_initialize)
源码分析,objc- ...
Category - load
+load
+load方法会在runtime加载类、分类时调用
每个类、分类的+load,在程序运行过程中只调用一次
调用顺序
先调用类的+load
按照编译先后顺序调用(先编译,先调用)
调用子类+load之前会先调用父类的+load
再调用分类的+load
按照编译先后顺序调用(先编译,先调用)
objc4源码解读:objc-os.mm
_objc_init
load_images
prepare_load_methods
schedule_class_load
add_class_to_loadable_list
add_category_to_loadable_list
call_load_methods
call_class_loads
call_category_loads
源码分析
_objc_init
1234567891011121314151617181920/************************************************************************ _objc_init* Boo ...
Category - 底层结构
底层结构12345678struct _category_t { const char *name; struct _class_t *cls; const struct _method_list_t *instance_methods; const struct _method_list_t *class_methods; const struct _protocol_list_t *protocols; const struct _prop_list_t *properties;};
加载处理过程
通过Runtime某个类的所有Category数据
把所有Category的方法,属性,协议数据,合并到一个在数组中
后面参与编译的Category数据,会在数组的前面
将合并后的分类数据(方法,属性,协议),插入到类原来数据的前面
源码解读顺序
objc-os.mm
_objc_init
map_images
map_images_nolock
objc-runtim-new.mm
_read_images
remeth ...
KVO & KVC
KVO
KVO的全称是Key-Value Observing,俗称“键值监听”,可以用于监听某个对象属性值的改变
添加KVO方法
1234567891011121314151617self.person = [[Person alloc] init];// 给person对象添加KVO监听NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;[self.person addObserver:self forKeyPath:@"age" options:options context:@"123"];// observeValueForKeyPath:ofObject:change:context:// 当监听对象的属性值发生改变时,就会调用- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDi ...
OC语法
Objective-c语法Objective-C的本质
平时编写的OC代码,底层实现其实都是C/C++代码
1Objective-C -> C/C++ -> 汇编语言 -> 机器语言
OC的面向对象都是基于C/C++的数据结构实现的,即 结构体
NSObject的底层实现123456789@interface NSObject { Class isa;}@end底层结构体形式:struct NSObject_IMPL { Class isa;}
创建一个实例对象,至少需要多少内存?
至少需要8个字节12#import <objc/runtime.h>class_getInstanceSize([NSObjcet class]);
创建一个实例对象,实际上分配了多少内存?
实际分配了16个字节
底层是Buckets size, 16, 32, 48, 64…. 都是16的位数12#import <objc/runtime.h>malloc_size( ...
iOS之一般商城应用中物品属性选择界面+购物车功能
本实例直接从当前项目中拉出来,实现的功能简单,但是在自己实现的时候用的代码老多多,而且当前只接收两组属性,不过属性实现了自动向下布局,超出屏幕可以上下滑动,但封装性不强,希望得到牛人指点。下面简单介绍实现方法。
1.购物车属性选择功能
1. 获取物品属性信息,并将数据直接转换为模型数据。12345678910111213141516171819202122/** * 获取 商品属性 数据 */- (void)getGoodAttrData { NSString *URL = [NSString stringWithFormat:@"%@/App/Sylm/yclist",SERVERURL]; NSMutableDictionary *paramas = [NSMutableDictionary dictionary]; paramas[@"method"] = @"goods_attr"; paramas[@"goods_id"] = @"11" ...
iOS应用之支付宝集成总结
上一个项目当中有用到支付宝的支付功能,但现在这个项目里因为集成了阿里百川的SDK,不能再简单的ctrl+c,然后ctrl+v,所以期间遇到一些小问题,配合后台(司马同学)一起把支付宝的功能给完成,在此做个简单的分享。
1.集成支付宝的方法
首先,回顾一下上一个项目中支付宝集成的图文方法,从官方支付宝开放平台下载所需的文件,解压支付宝钱包支付接口开发包2.0标准版(iOS 15.0.2),整理相关文件,如下图:
把必须的文件(AlipaySDK)导入工程中,如下图:
然后按照官方文档导入相应的依赖,如图:
在此,默认你的工程已经适配过9.0,下面就直接上代码:
1234// 导入头文件#import "Order.h"#import "DataSigner.h"#import <AlipaySDK/AlipaySDK.h>
生成订单描述并对商户私钥签名,然后拼接参数唤起支付宝
1234567891011121314151617181920212223242526272829303132333435363 ...
iOS应用之银联支付集成
银联支付集成,十分简单,前台做工作很少。
借助于前几天项目刚刚上线,也在此继续分享下银联支付的相关方法和总结。本次分享的为支持纯无卡交易。
鉴于上两次的支付分享,本次所做的内容比较简单,签名工作移到了后台进行,前端所做的工作非常少,只需要往后台POST过去商品价格,后台对订单进行相应的签名,返回签名后的tn字符串即可。
1.事前准备工作
添加工程所需的银联支付(iOS)SDK,如下图:
2. 开发流程
导入头文件 #import "UPPayPlugin.h" 以及设置代理 <UPPayPluginDelegate>
触发唤起银联支付的方法(本次对订单的签名处理都在后台进行,在此附上后台银联支付SDK)。
1234567891011121314151617#pragma mark - 银联支付相关方法- (IBAction)yinlianPayAct { NSString *strUrl = [NSString stringWithFormat:@"%@/App/Index/index/",SER ...












