git 常用命令

查看、添加、提交、删除、找回,重置修改文件

git help <command> # 显示command的help

git show # 显示某次提交的内容 git show $id

git co — <file> # 抛弃工作区修改

git co . # 抛弃工作区修改

git add <file> # 将工作文件修改提交到本地暂存区

git add . # 将所有修改过的工作文件提交暂存区

git rm <file> # 从版本库中删除文件

git rm <file> –cached # 从版本库中删除文件,但不删除文件

git reset <file> # 从暂存区恢复到工作文件

git reset — . # 从暂存区恢复到工作文件 继续阅读“git 常用命令”

iOS-自带二维码集成

关于苹果自带二维码扫描和生成代码如下:

// 以下为二维码读取部分(github):

#import <AVFoundation/AVFoundation.h>
@property (strong, nonatomic) AVCaptureSession *session;
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *previewLayer;
#pragma mark - 读取二维码
- (void)readQRCoder
{
    // 1. 摄像头设备
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    // 2. 设置输入
    // 因为模拟器是没有摄像头的,因此在此最好做一个判断
    NSError *error = nil;
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
    if (error) {
        NSLog(@"没有摄像头-%@", error.localizedDescription);
        return;
    }
    // 3. 设置输出(Metadata元数据)
    AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
    // 3.1 设置输出的代理
    // 说明:使用主线程队列,相应比较同步,使用其他队列,相应不同步,容易让用户产生不好的体验
    [output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    // 4. 拍摄会话
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
    // 添加session的输入和输出
    [session addInput:input];
    [session addOutput:output];
    // 4.1 设置输出的格式
    // 提示:一定要先设置会话的输出为output之后,再指定输出的元数据类型!
    [output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
    // 5. 设置预览图层(用来让用户能够看到扫描情况)
    AVCaptureVideoPreviewLayer *preview = [AVCaptureVideoPreviewLayer layerWithSession:session];
    // 5.1 设置preview图层的属性
    [preview setVideoGravity:AVLayerVideoGravityResizeAspectFill];
    // 5.2 设置preview图层的大小
    [preview setFrame:self.view.bounds];
    // 5.3 将图层添加到视图的图层
    [self.view.layer insertSublayer:preview atIndex:0];
    self.previewLayer = preview;

    // 6. 启动会话
    [session startRunning];
    self.session = session;
}
#pragma mark - 输出代理方法
// 此方法是在识别到QRCode,并且完成转换
// 如果QRCode的内容越大,转换需要的时间就越长
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    // 会频繁的扫描,调用代理方法
    // 1. 如果扫描完成,停止会话
    [self.session stopRunning];
    // 2. 删除预览图层
    [self.previewLayer removeFromSuperlayer];
    NSLog(@"%@", metadataObjects);
    // 3. 设置界面显示扫描结果
    if (metadataObjects.count > 0) {
        AVMetadataMachineReadableCodeObject *obj = metadataObjects[0];
        // 提示:如果需要对url或者名片等信息进行扫描,可以在此进行扩展!
        _label.text = obj.stringValue;
    }
}

// 以下为二维码生成部分(github)

#import <CoreImage/CoreImage.h>
// 1. 实例化一个滤镜
CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 1.1 设置filter的默认值
// 因为之前如果使用过滤镜,输入有可能会被保留,因此,在使用滤镜之前,最好设置恢复默认值
[filter setDefaults];
// 2. 将传入的字符串转换为NSData
NSData *data = [@"http://www.baidu.com" dataUsingEncoding:NSUTF8StringEncoding];
// 3. 将NSData传递给滤镜(通过KVC的方式,设置inputMessage)
[filter setValue:data forKey:@"inputMessage"];
// 4. 由filter输出图像
CIImage *outputImage = [filter outputImage];
// 5. 将CIImage转换为UIImage
UIImage *qrImage = [UIImage imageWithCIImage:outputImage];

Objective-C Runtime机制

关于runtime 网上有很多文章了,他的原理,以及调用。关于相关函数名解释在这里,我也就不一一列举了。直接干货走起

#import <objc/runtime.h>
#import <objc/message.h>
#pragma mark - 利用rutime动态修改其他类内部变量方法
- (void)exchangeClassVar
{
    TKTest *t = [[TKTest alloc] init];
    // 先定义一个数量
    unsigned int count = 0;
    // 获得该class的变量个数
    Ivar *test = class_copyIvarList([TKTest class], &count);
    for (int i = 0; i<count; i++) {
        Ivar var = test[i];
        // 将IVar变量转化为字符串
        const char *a = ivar_getName(var);
        // 获取IVar的类型
        const char *b = ivar_getTypeEncoding(var);
        // 取一个临时变量 char无法直接作比较
        NSString *exa = [NSString stringWithFormat:@"%s",a];
        if ([exa isEqualToString:@"_name"]) {
            // 在此改变内部name变量的属性
            object_setIvar(t, var, @"chengong");
        }
        NSLog(@"%s----%s",a,b);
    }
    NSLog(@"%@",[t description]);
}
#pragma mark - 利用rutime动态修改其他类内部私有函数
//具体的实现,即IMP所指向的方法
int myAddingFunction(id self, SEL _cmd, NSString *str, NSString *str1)
{
    NSLog(@"I am added funciton%@---%@",str,str1);
    return 10;
}
- (void)exchangeClassMethod
{
/*
i:返回值类型int,若是v则表示void
@:参数id(self)
::SEL(_cmd)
@:id(str)
*/
    class_addMethod([TKTest class], @selector(method::), (IMP)myAddingFunction, "i@:@@");
    TKTest *t = [[TKTest alloc] init];
    // 先定义一个数量
    unsigned int count = 0;
    // 获得该class的私有函数个数
    Method *m = class_copyMethodList([TKTest class], &count);
    for (int i = 0; i<count; i++) {
        SEL name = method_getName(m[i]);
        // 方法名
        NSString *methodName = [NSString stringWithCString:sel_getName(name) encoding:NSUTF8StringEncoding];
//      NSLog(@"%@",methodName);
}
    //尝试调用新增的方法
    [t performSelector:@selector(method::) withObject:@"haha" withObject:@"ooooo"];
}
#pragma mark - 方法之间的互换
- (void)exchangeMethod
{
    Method method1 = class_getInstanceMethod([NSString class], @selector(lowercaseString));
    Method method2 = class_getInstanceMethod([NSString class], @selector(uppercaseString));
    method_exchangeImplementations(method1, method2);
    NSLog(@"lowcase :%@", [@"CE shi" lowercaseString]);
    NSLog(@"uppercase :%@", [@"CE shi" uppercaseString]);
}
#pragma mark - 动态添加一个属性
- (void)setTest:(TKTest *)test
{
    objc_setAssociatedObject(self, &addTestKey, test, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (TKTest *)test
{
    return objc_getAssociatedObject(self, &addTestKey);
}