美文网首页
iOS -开发笔记。

iOS -开发笔记。

作者: DylanPP | 来源:发表于2017-02-16 11:19 被阅读573次

    不积跬步无以至千里。再愚蠢的Bug,也是进步的垫脚石。

    图片渲染模式

    imageWithRenderingMode:
    UIImageRenderingModeAutomatic,
    //根据图片的使用环境和所处的绘图上下文自动调整渲染模式。
    UIImageRenderingModeAlwaysOriginal,
    // 始终绘制图片原始状态
    UIImageRenderingModeAlwaysTemplate,
    // 始终根据Tint Color绘制图片,忽略图片的颜色信息。

    导航栏控制器

      self.edgesForExtendedLayout = UIRectEdgeNone;//tableview不延展至导航栏下
      self.automaticallyAdjustsScrollViewInsets=NO;//默认YES->控件尺寸从导航栏下面开始(滑动tableview可滑动至导航栏下)
    

    info.plist

    添加App需要的一些设备权限:
    相机NSCameraUsageDescription
    相册NSPhotoLibraryUsageDescription
    通讯录NSContactsUsageDescription
    始终访问位置NSLocationAlwaysUsageDescription
    位置NSLocationUsageDescription
    在使用期间访问位置NSLocationWhenInUseUsageDescription
    麦克风NSMicrophoneUsageDescription
    访问蓝牙NSBluetoothPeripheralUsageDescription
    访问日历NSCalendarsUsageDescription
    访问媒体资料库NSAppleMusicUsageDescription
    访问健康分享NSHealthShareUsageDescription
    访问健康更新NSHealthUpdateUsageDescription
    访问运动与健身NSMotionUsageDescription
    访问提醒事项NSRemindersUsageDescription


    示例

    SVN提交冲突问题

    .xcodeproj工程文件冲突,往往是多人同时做了例如增删文件等行为,那么保存/提交就会出现project.pbxproj文件冲突,svn就会在文件中加上>>>>> 还有<<<<<来区分谁做的修改,只要把这个文件用编辑器打开,搜mine到了把这些冲突标记删除,将服务器和自己的修改都保留应该就没事了。

    解决方法如下:

    1.右键点击.xcodeproj,选择显示包内容;
    2.双击打开project.pbxproj文件;
    3.找到类似如下的冲突信息(可用command + F 搜索)
    4.删除

        <<<<<< .mine
        =======
        >>>>>>> .r156
    

    留下下面的:

        .... in Resources */,
        ... in Resources */,
    

    5.保存文件,退出,再打开即可使用。

    异步加载网络图片

    -(void)downloadImageWithUrl:(NSString *)imageDownloadURLStr withImgView:(UIImageView *)_imageView{
        __block UIImage *image = [[UIImage alloc] init];
        NSURL *imageDownloadURL = [NSURL URLWithString:imageDownloadURLStr];
        dispatch_queue_t asynchronousQueue = dispatch_queue_create("imageDownloadQueue", NULL);
        dispatch_async(asynchronousQueue, ^{
            NSError *error;
            NSData *imageData = [NSData dataWithContentsOfURL:imageDownloadURL options:NSDataReadingMappedIfSafe error:&error];
            if (imageData) {
                image = [UIImage imageWithData:imageData];
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                [_imageView setImage:image]
            });
        });
    }
    

    移除Main.storyboard

    • 工程配置中移除关联
      TARGETS->Deploymeny info 清空Main interface 选项中值
    • 移除Main.storyboard关联类
      点击Main.storyboard文件 选择 Show the identity inspector -> Custom Class 清除Class关联
    • 删除Main.storyboard文件。

    Wordspace 管理多工程 找不到头文件

    • 方法一: Build setting -> User Header Search Paths 添加$(BUILT_PRODUCTS_DIR) 但是不能simulator 与真机随意切换 项目中直接使用真机 未尝试simulator,暂未处理。
    • 方法二:Build setting -> Header search paths 编辑:../工程名或静态库名 或者 ../../工程名或静态库名。解决。

    制作静态库失败

    error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't locate file for: -lQmyKit
    error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: file: -lQmyKit is not an object file (not allowed in a library)
    
    • 检查Library Search Paths 是否正确。
      $(PROJECT_DIR)/

    设置启动页为LaunchImage

    • 1.在Assets.xcassets中新建LaunchImage
      2.在项目TARGETS->General->App Icons and Launch Images中设置 Launch Images Source 为LaunchImage,并将Launch Screen File 设为空
      3.在LaunchImage 添加相应启动图片。

    iOS系统升级导致无法真机调试

    倘若你升级的真机系统,而Xcode还是旧版本,真机调试时会出现Could not find Developer Disk Image。升级Xcode,又很慢。Just do it: 进入下面路径:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport 导入你需要的包文件SDK(百度下载)。
    若还是不行 上官网更新Xcode:https://developer.apple.com/download/

    Archives 打包出现 Other Items

    原因为打包时产生了一些不必要的文件
    解决方法:

    • 静态库的skip install设置为YES
    • 将子项目中Build Phases→Copy Headers中的所有头文件拉到Project下,即Public和Private下不能有文件
    • 清空Build Settings→Deployment→Installation Directory选项的内容

    CocoaPods Podfile 文件

    platform:ios,'8.0'
    target 'AFNetworkingDemo' do
      pod 'AFNetworking', '~> 3.0'
    end
    

    Ruby:
    查看本地ruby资源:gem source -l

    查看ruby cocoapods版本 ruby -v pod --version

    https://rubygems.org/
    移除https://rubygems.org/替换为https://gems.ruby-china.com/
    gem source --remove https://rubygems.org/
    gem source --add https://gems.ruby-china.com/
    安装cocospods
    sudo gem install cocoapods

    代理属性为何使用weak

    代理的销毁不能由当前遵从协议的类控制,倘若属性为strong,则会造成循环应用。

    删除数组中重复对象

    NSArray *newArr = [oldArr valueForKeyPath:@“@distinctUnionOfObjects.self"];
    

    颜色转图片

    + (UIImage *)imageWithColor:(UIColor *)color {
      CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
      UIGraphicsBeginImageContext(rect.size);
      CGContextRef context = UIGraphicsGetCurrentContext();
     
      CGContextSetFillColorWithColor(context, [color CGColor]);
      CGContextFillRect(context, rect);
     
      UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
     
      return image;
    }
    

    Pod 错误

    down下来的项目出现以下错误时
    方法1. 进入项目根目录 执行pod update||pod install即可。

    diff: /../Podfile.lock: No such file or directory
    diff: /Manifest.lock: No such file or directory
    error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
    

    方法2.Build Phases勾选 Run script only when installing

    执行延迟函数

      dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC);
      dispatch_after(delay, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
          
        });
    

    异步下载数据

     dispatch_queue_t asynchronousQueue = dispatch_queue_create("imageDownloadQueue", NULL);
        //创建异步线程
        dispatch_async(asynchronousQueue, ^{
            //网络下载图片  NSData格式
            NSError *error;
            NSData *imageData = [NSData dataWithContentsOfURL:imageDownloadURL options:NSDataReadingMappedIfSafe error:&error];
            if (imageData) {
                image = [UIImage imageWithData:imageData];
            }
            //回到主线程更新UI
            dispatch_async(dispatch_get_main_queue(), ^{
                [_imageView setImage:image];
                [_myActivity stopAnimating];
            });
        });
    

    CADisplayLink

    使用CADisplayLink NStimer绘制页面时默认RunLoopMode为NSDefaultRunLoopMode。此时主线程中操作某些UI事件(例如UITableview滑动)会造成 NSDefaultRunLoopMode 模式中注册的事件是不会执行,此时mode被切换为NSEventTrackingRunLoopMode,若要保证定时器绘制不被影响可选择NSRunLoopCommonModes模式。

    Xcode编译第三方库,出现

    Undefined symbols for architecture arm64:   
    "_OBJC_CLASS_$_xxx", referenced from:   
    

    原因1.相关工程文件未导入:
    处理方式:Build Phase->Compile Sources 添加该库.m文件。
    原因2.找不到对应的编译包:
    处理方式:加入libc++库。

    Xcode升级后联想功能失效无法Command类库处理方法

    Xcode->Preferences->Location 
    

    进入DerivedData 删除该文件夹下的内容 重启Xcode。

    CADisplayLink和NSTimer的区别

    NSTimer占用系统资源较多
    NSTimer使用完后,一定要销毁,把它设置成nil。
    CADisplayLink本来就在进程中,每秒进行60次。
    核心动画的时候,最好使用CADisplayLink

    防止图片上传发生偏转

    + (UIImage *)fixOrientation:(UIImage *)aImage {
        
        // No-op if the orientation is already correct
        if (aImage.imageOrientation == UIImageOrientationUp)
            return aImage;
        
        // We need to calculate the proper transformation to make the image upright.
        // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
        CGAffineTransform transform = CGAffineTransformIdentity;
        
        switch (aImage.imageOrientation) {
            case UIImageOrientationDown:
            case UIImageOrientationDownMirrored:
                transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
                transform = CGAffineTransformRotate(transform, M_PI);
                break;
                
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
                transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
                transform = CGAffineTransformRotate(transform, M_PI_2);
                break;
                
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
                transform = CGAffineTransformRotate(transform, -M_PI_2);
                break;
            default:
                break;
        }
        
        switch (aImage.imageOrientation) {
            case UIImageOrientationUpMirrored:
            case UIImageOrientationDownMirrored:
                transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
                transform = CGAffineTransformScale(transform, -1, 1);
                break;
                
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRightMirrored:
                transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
                transform = CGAffineTransformScale(transform, -1, 1);
                break;
            default:
                break;
        }
        
        // Now we draw the underlying CGImage into a new context, applying the transform
        // calculated above.
        CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
                                                 CGImageGetBitsPerComponent(aImage.CGImage), 0,
                                                 CGImageGetColorSpace(aImage.CGImage),
                                                 CGImageGetBitmapInfo(aImage.CGImage));
        CGContextConcatCTM(ctx, transform);
        switch (aImage.imageOrientation) {
            case UIImageOrientationLeft:
            case UIImageOrientationLeftMirrored:
            case UIImageOrientationRight:
            case UIImageOrientationRightMirrored:
                // Grr...
                CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
                break;
                
            default:
                CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
                break;
        }
        
        // And now we just create a new UIImage from the drawing context
        CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
        UIImage *img = [UIImage imageWithCGImage:cgimg];
        CGContextRelease(ctx);
        CGImageRelease(cgimg);
        return img;
    }
    

    CALayer中anchorPoint、position、frame关系

    • frame中的X,Y表示sublayer左上角相对于supLayer的左上角的距离。
    • position中的X,Y表示sublay锚点相对于supLayer的左上角的距离。
    • anchorPoint中的X,Y表示锚点的x,y的相对距离比例值。

    当确定锚点,改变frame时, position的值为:

    position.x = frame.origin.x + anchorPoint.x * bounds.size.width;  
    position.y = frame.origin.y + anchorPoint.y * bounds.size.height;
    

    确定锚点, 改变position时, frame的值为:

    frame.origin.x = position.x - anchorPoint.x * bounds.size.width;  
    frame.origin.y = position.y - anchorPoint.y * bounds.size.height;
    

    改变锚点, frame的值变化为

    frame.origin.x = - anchorPoint.x * bounds.size.width + position.x;  
    frame.origin.y = - anchorPoint.y * bounds.size.height + position.y
    

    设置字体颜色

    - (NSMutableAttributedString *)setColorTextStr:(NSString *)title
                                     withTextColor:(UIColor *)colorText
                                    withLabelTitle:(NSString *)content
                                    withTitleColor:(UIColor *)colorContent{
        
        NSString *textContent = [NSString stringWithFormat:@"%@  %@",title,content];
        NSRange rangeTitle   =[textContent rangeOfString:title];
        NSRange rangeContent =[textContent rangeOfString:content];
        NSMutableAttributedString *textAttr = [[NSMutableAttributedString alloc]initWithString:textContent];
        [textAttr addAttribute:NSForegroundColorAttributeName value:colorText range:rangeTitle];
        [textAttr addAttribute:NSForegroundColorAttributeName value:colorContent range:rangeContent];
        [textAttr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:15] range:NSMakeRange(0,textContent.length)];
        return textAttr;
        
    }
    

    Xcode新建工程编译失败

    Safe Area Layout Guide Before IOS 9.0

    处理方式:选中stroyboard ->show the file inspector -> 去掉勾选的Use Safe Area Layout Guide

    调用safari打开链接

    NSString *textURL = @"https://www.baidu.com/";  
    NSURL *cleanURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@", textURL]];  
    [[UIApplication sharedApplication] openURL:cleanURL];  
    

    多人开发打包时出现has iOS Distribution certificate but its private key is not installed

    原因在于苹果规定.cer证书只能存在一个电脑上,其他开发者使用时即便从开发者中心download也是无效的,因此 如果另一台电脑想要用的话,需要导出为.p12 file ,安装到其他电脑上。

    关于Debug模式下weak修饰的view正常显示,Release模式View无法显示问题

    Debug和Release和内存分配和释放方式是不同的,Debug模式下内存会延迟释放,weak的对象会延迟,但Release下进行了优化,所以达到释放条件会立即释放,从而造成weak修饰的view在Release模式下无法正常显示。调整为Strong即可。

    反射机制:

    对于任意一个类,都能够知道这个类的都有属性和方法
    对于任意一个对象,都能够调用它的任意一个方法和属性

    毒药与小白鼠

    问题:1000瓶水有1瓶水有毒,老鼠喝一滴24小时后就会死,问最少需要多少只老鼠,以及如何检测出毒药?
    1.至少需要10只老鼠。采用二分法计算小白鼠数量。
    第一次: 将1-500瓶兑在一起喝。
    如果老鼠死了,则拿另一只老鼠去品尝501-725瓶兑的药水。否则去喝2-250瓶兑的水。
    采用如此二分法,因为2^10>1000 2^9<1000,所以10次就可以找出。
    2.取10个烧杯编号1->10
    给1000个试剂分别标上如下标签(10位长度):
    0000000001 (第1瓶)
    0000000010 (第2瓶)
    0000000011 (第3瓶)
    ……
    1111101000 (第1000瓶)
    从编号最后1位是1的所有的试剂里面取出1滴混在一起(比如从第一瓶,第三瓶,。。。里分别取出一滴混在一起)并倒入编号为1的烧杯中。以此类推,从编号第一位是1的所有的试剂里面取出1滴混在一起并倒入编号为10的烧杯中。现在得到有10瓶烧杯编号的混合液,小白鼠排排站,分别标上10,9,。。。1号,并分别给它们灌上对应号码的混合液。24小时过去了,过来验尸吧:
    从左到右,死了的小白鼠贴上标签1,没死的贴上0,最后得到一个序号,把这个序号换成10进制的数字,就是有毒的那瓶水的编号。
    检验一下:假如第一瓶有毒,按照0000000001 (第1瓶),说明第1号混合液有毒,因此小白鼠的生死符为0000000001(编号为1的小白鼠挂了),0000000001二进制标签转换成十进制=1号瓶有毒;假如第三瓶有毒,0000000011 (第3瓶),第1号和第2号混合液有毒,因此小白鼠的生死符为00000011(编号为1,2的鼠兄弟挂了),0000000011二进制标签转换成十进制=3号瓶有毒。

    Error: Multiple commands produce

    移除Build phase > Copy Bundle Resource 中找到info.plist

    #include <string> 'string' file not found

    Xcode9->Xcode10 工程使用的是objc++ xcode升级后由于 libstdc++被弃用 原来在build settings 使用的 libstdc++需要修改为 libc++ 同时导入该头文件的.m->.mm 。 success!

    Xcode 提示Revoke certificate

    Revoke certificate Your account already has a signing certificate for this machine but it is not present in your keychain. To create a new one, you must first revoke the existing certificate.
    

    先不要急着revoke 虽然可以很快解决问题。。。当然如果你是个人开发,随便你怎么revoke。

    我遇到这个问题时,是因为带薪拉屎后回到岗位上发现macMini突然不知什么原因呼呼的响,而且电脑卡的要命,于是乎我重装了系统。。。接下来打开Xcode开始敲代码时,Xcode提醒我Your account already has a signing ..... revoke the existing certificate。纳尼?这个问题我还没有遇到过,Revoke会不会是核按钮?尤其是合作开发的时候,会不会影响到其他开发者的使用?似乎当然不会!哈哈因为删除的是这个账号下,本机签名的开发者证书。 67121F8A-DA5D-4189-A2B6-0407F7640DA3.png
    怎么会影响到其他人的开发者账号? 04C557DB-FC4B-4ADC-8C85-CD4FA9DDBD7D.png

    ps:使用的是合作公司的开发账号,公用一个企业发布证书,revoke会收到人家的邮箱会收到删除提醒邮件,这多尴尬的事情。而且很多时候你可能收到离职信。。。建议不要revoke。
    那么到底怎么解决?
    从证书创建者电脑上导出一份p12开发者证书。

    Charles 手机安装好Charles证书仍抓不到https请求

    iOS 10.3系统以后,需要在 设置→通用→关于本机→证书信任设置启用完全信任Charles证书。
    Charles 配置Cocoa开发者社区

    ld: symbol(s) not found for architecture arm64

    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    这种编译失败情况多种
    1.重复导入相关文件或头文件名
    2.Other Linker Flags 设置问题:-ObjC ,-all_load
    3.缺少必要系统库。

    IQKeyboardManager 引起电池栏透明

    IQUIView+Hierarchy.m文件修改
    -(UIViewController*)topMostController 方法中的代码

    -(UIViewController *)topMostController
    {
        UIViewController  *rootController = [UIApplication  sharedApplication].keyWindow.rootViewController;
        if ([rootController isKindOfClass:[UITabBarController class]]) {
            UITabBarController *tabBarController = (UITabBarController *)rootController;
            UINavigationController *navController = tabBarController.selectedViewController;
            UIViewController *viewController = (UIViewController *)navController.visibleViewController;
            while (viewController.presentedViewController) {
                viewController = (UIViewController *)viewController.presentedViewController;
            }
            return viewController;
        } else if ([rootController isKindOfClass:[UINavigationController class]]) {
            UINavigationController *navController = (UINavigationController *)rootController;
            return navController.visibleViewController;
        } else if ([rootController isKindOfClass:[UIViewController class]]) {
            return rootController;
        } else {
            return nil;
        }
     
    }
    

    Duplicate symbol _kXXX in:

    ViewA.o;
    ViewB.o;
    通常定义常量使用static const 修饰 ,若声明的kXXX变量不加static 编辑器会默认创建“外部符号”<enternal symbol>,若其他编译单元存在同名变量kXXX则会导致编译失败。

    关于Compile Sources AS: Objective C++ 编译失败

    第三方库冲突
    Other Linker flags 加入 (inherited) User Header Paths 加入(PODS_ROOT) +$(PODS_ROOT)/第三方库地址

    好记性不如烂笔头。

    END

    GithubZhaoBinLe

    相关文章

      网友评论

          本文标题:iOS -开发笔记。

          本文链接:https://www.haomeiwen.com/subject/pbvzittx.html