zoukankan      html  css  js  c++  java
  • IOS开发基础知识--碎片42

    1:报thread 1:exc_bad_access(code=1,address=0x70********) 闪退

    这种错误通常是内存管理的问题,一般是访问了已经释放的对象导致的,可以开启僵尸对象(Zombie Objects)来定位问题:

    在Xcode的菜单:

    Product->Scheme->Edit Scheme->Run

    右边的选项中,选中Enable Zombie Objects,就可以查看详细的错误信息;

     

    2:静态库(SDK)知识点

    1.1 静态库和动态库的存在形式:
    静态库:.a 和 .framework
    动态库:.dylib 和 .framework
    
    1.2 静态库和动态库的区别
    静态库:链接时,静态库会被完整地复制到可执行文件中,被多次使用就有多份冗余拷贝
    动态库:链接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存
    
    注意:项目中如果使用了动态库,会苹果拒接
    
    1.3 静态库文件的版本(4种)
    真机-Debug版本
    真机-Release版本
    模拟器-Debug版本
    模拟器-Release版本
    
    1.3.1 Debug(调试)版本
    1.含完整的符号信息,以方便调试
    2.不会对代码进行优化
    
    1.3.2 Release(发布)版本
    1.不会包含完整的符号信息
    2.的执行代码是进行过优化的
    3.的大小会比Debug版本的略小
    4.在执行速度方面,Release版本会更快些(但不意味着会有显著的提升)
    
    所以我们一般开发中都打包Release(发布)版本,提供外界,注意分别在两种模式下生成后再合并;
    
    设备的CPU架构简介(补充知识)
    
    模拟器:
    4s~5 : i386
    5s~6plus : x86_64
    
    真机:
    3gs~4s : armv7
    5~5c : armv7s (静态库只要支持了armv7,就可以跑在armv7s的架构上)
    5s~6plus : arm64

    a:因为动态的.framework苹果上架是不允许,所以只能以静态的方式;制作静态库时记得选择目标要运行的IOS版本;

    b:关于资源文件bundle在生成framework后会有包含,可以手动把bundle移出来,然后一起给调用者,否则放在framework在项目中无法引入bundle,一直无法识别出来;

    c:查看目前支持的CPU架构,地址要正确,然后运用lipo -info (下面这个是针对framework,如果是.a 可以直接对lipo -info xxxx.a查看)

    wjy-MacBook-Pro:Products wujunyang$ cd /Users/wujunyang/Library/Developer/Xcode/DerivedData/jiaCoreSDK-bgpoefwfpffqejccohhhngirohwn/Build/Products/Debug-iphoneos 
    wjy-MacBook-Pro:Debug-iphoneos wujunyang$ lipo -info jiaCoreSDKLib.framework/jiaCoreSDKLib
    Architectures in the fat file: jiaCoreSDKLib.framework/jiaCoreSDKLib are: armv7 arm64 

    framework合并指令

    lipo -create Debug-iphoneos/jiaCoreSDK_Share.framework/jiaCoreSDK_Share Debug-iphonesimulator/jiaCoreSDK_Share.framework/jiaCoreSDK_Share -output jiaCoreSDK_Share

    注意framework是针对.framework里面的文件进行合并,然后生成一个,再把它替换其中一个.framework,这个便是我们想要的文件;

    关于.a的合并可以见下面的文章;

    d:.a跟.framework不同,.a要把开放的头文件都放到调用的项目中,而.framework可以只开放一个头文件出来;但是两个里面的public放头文件都还是必须;

    e:制作静库时记得把tagerts中的Build Settings的Mach-O Type设置成Static Library

    f:注意设置.a或.framework技术的最低IOS版本;在生成时分别在真机跟模拟器上生成然后再合并;

    g:关于如何创建.a及.framework的知识点:

    地址:http://www.jianshu.com/p/8f5b9855efb8【iOS 静态库开发】

    地址:http://www.cnblogs.com/richard-youth/p/4856841.html【iOS静态库小结--(yoowei)】

    地址:http://www.jianshu.com/p/c305175bfab2【iOS开发拓展篇—静态库】

    地址:https://github.com/wujunyang/jiaCoreSDK【小实例】

    地址:https://www.sdk.cn/news/3342 【静态库包含其它静态库SDK应该注意的问题】

    3:iOS代理(protocol与delegate)很形象的实例

    让我们先来看下protocol和delegate运用的代码,有一个整体的了解

    假定有两个类:personOne和personTwo

    personOne是委托者,personTwo是代理者。

    pesonOne.h

    #import <Foundation/Foundation.h>
    @protocol SomeThing<NSObject>
    //需要被代理的事件
    - (void) doSomeThing:( NSString *)someThing;
    @end
    @interface PersonOne : NSObject
    //有件事情需要别人替自己做
    //代替自己的人必须要会做这个事情,需要知道了解相关的协议;
    @property (weak) id <SomeThing> delegate;
    //weak:不需要为这个delegate分配空间,因为做完就走人了。
    //id:只要是个对象就可以。
    @end

    personTwo.h

    #import <Foundation/Foundation.h>
    #import "PersonOne.h"
    @interface PersonTwo : NSObject<SomeThing>
    //加上<SomeThine>表示代理人知道了相关协议,可以接手代理。
    @end

    personTwo.m

    #import "PersonTwo.h"
    @implementation PersonTwo
    //代理开始去做委托方交代的事情(必须实现)
    -(void) doSomeThing:(NSString*) someThing
    {    
        NSLog(@"%@............",someThing);
    }
    @end

    双方真正的实现相互关联

    main.m

    #import <Foundation/Foundation.h>
    #import "PersonTwo.h"
    #import "PersonOne.h"
    int main(intargc, const char * argv[]) {
         @autoreleasepool{
      //真正的实现代理方与委托方之间的关联
        PersonOne *pA = [[PersonOne alloc]init];         
        PersonTwo *pB = [[PersonTwo alloc]init];         
      //pB代替pA去完成事件
        pA.delegate = pB;
      //用 pA.delegate 判断是否存在pB
      //用 [pA.delegate respondsToSelector:@selector(doSomeThing:)] 判断pB是否实现了要求的方法。
    if (pA.delegate && [pA.delegate respondsToSelector:@selector(doSomeThing:)]) {
      //pA提供一个参数给pB(只负责提供参数,不管具体使用)
        [pA.delegate doSomeThing:@"hello world"];
            }
        }
        return  0;
      }

    用一个形象的比喻来说明这一整个代理事件:

    一个咖啡厅生意非常好,老板 (personOne) 决定招一个咖啡师来帮忙。于是就贴出了一则公告 (delegate)

    公告内容:(protocol)

    招聘一名咖啡师,有一年经验以上。会调酒者优先录取。

    从这个公告中,可以知道两点:

    1-会做咖啡,并且有一年以上的经验是 必须的条件 (@required:必须实现的方法)

    2-会调酒是 可选,非必须的条件 (@optional:可选 实现的方法(可以全部都不实现))

    所以,凡是前来应聘的必须都要满足第一个条件,第二个条件只是加分项而已,并非不可缺的。

    招到了员工B以后,老板要求B做一杯摩卡。至于B怎么做,老板是不会关心的,他只关心结果。

    ([pA.delegate doSomeThing:@"hello world"];) ——>[老板.delegate 做咖啡:@"摩卡"];)

     

    3.2 另外一个关于导演跟助手的故事

    @protocol filmAssistantProtocol   //协议名字
    
    @required
    /*
     1:能寻找合适的胶片冲洗厂,进行胶片的冲洗(必须).
     2:后期音频合成,可以将录制好的音频合成到胶片里面(必须).
     3:需找海报制作商(必须).
     4:负责片场治安秩序(非必须)
     */
    
    
    +(void) filmDeveloped;  //冲洗照片
    +(void) audioProcess;   //音频合成
    +(void) posterMake ;   //海报制造
    
    
    
    @optional
    -(void) siteSecurity; //现成安保
    
    @end

    导演类:

    //
    //  Director.h
    //  Film
    //
    //  Created by Alex on 4/9/16.
    //  Copyright © 2016 Alex. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import "filmAssistantProtocol.h"
    
    //#import "剧本医生协议.h"
    
    @interface Director : NSObject
    
    @property (strong, nonatomic) NSString   *directorName;  //定义导演的名字
    
    
    //
    
    /*定义一个后期制作的代理 backAssistant,这个代理遵守 filmAssistantProtocol 这个
    协议,即:这个后期制作的代理 应该能干filmAssistantProtocol 这个协议里面定义的
    功能集合
     
    与通常我们见到的 
     @property(nonatomic, retain)  id <someProtocol>        delegate; 写法其实是一回事.
                                          |                   |
                                          |                   |
                                          V                   V
     @property(nonatomic, retain)  id<filmAssistantProtocol> backAssistant;
    
    */
    
    
    @property(nonatomic, retain) id<filmAssistantProtocol> backAssistant;
    
    /*我们目前只有一个代理,如果需要其他代理(比如剧本医生),将会是下面的写法*/
    
    //@property(nonatomic, retain) id<剧本医生协议> 剧本代理人;
    
    
    
    -(void) posterMake;  //印刷海报,导演自己也可以印刷海报
    -(void) introMyself; // 导演自我介绍的方法.
    
    
    
    
    @end
    //
    //  Director.m
    //  Film
    //
    //  Created by Alex on 4/9/16.
    //  Copyright © 2016 Alex. All rights reserved.
    //
    
    #import "Director.h"
    
    @implementation Director
    
    -(void)posterMake{
    
        NSLog(@"导演自己弄海报啦!!");
        
        
    }
    
    
    -(void) introMyself{
    
    
      NSLog(@"我是大导演,我的名字是:%@,我的助理(指针)是 %@ ",self.directorName,self.backAssistant);
    }
    
    @end

    助手类:

    //
    //  newSchool.h
    //  Film
    //
    //  Created by Alex on 4/9/16.
    //  Copyright © 2016 Alex. All rights reserved.
    //
    
    
    #import <Foundation/Foundation.h>
    #import "filmAssistantProtocol.h"
    @interface newSchool : NSObject<filmAssistantProtocol>  //实现了filmAssistantProtocol这个协议
    @property (strong, nonatomic) NSString   *girlname;
    //冲洗照片
    -(void) filmDeveloped;
    //音频合成
    -(void) audioProcess;
    //海报制造
    -(void) posterMake;
    @end
    //
    //  newSchool.m
    //  Film
    //
    //  Created by Alex on 4/9/16.
    //  Copyright © 2016 Alex. All rights reserved.
    //
    
    #import "newSchool.h"
     
    
    
    
    
    @implementation newSchool
    
    //冲洗照片
    
    +(void) filmDeveloped{
    
        NSLog(@"我以一种newSchool的方式去找人冲洗照片");
        
    }
    
    //音频合成
    
    +(void) audioProcess{
        
        NSLog(@"我以一种newSchool的方式去找人音频合成");
    
    }
    
     //海报制造
    -(void) posterMake{
        NSLog(@"我是%@ ,我以一种newSchool的方式去找人弄海报",[self girlname]);
    
    }
    
    
    
    
    @end

    实现:

    #import "ViewController.h"
    #import "Director.h"
    #import "newSchool.h"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSLog(@"程序开始了");
        Director* oneDirector = [[Director alloc] init]; //初始化一个导演
        
        oneDirector.directorName = @"PeterJ";    // PeterJ ,彼得杰克逊,指环王导演,这样让你们读代码好记.
    
        [oneDirector introMyself];   //导演介绍自己,虽然有"assistant"这个属性,但是还么有指定具体人.
        
        [oneDirector posterMake];   //导演自己也可以posterMake,因为他有这个方法.
        
        newSchool* oneGirl = [[newSchool alloc] init];  //定义一个新派的女学生,因为这个newSchool实现了那个协议,所以她就有那些能力.
        oneGirl.girlname = @"小花蝴蝶";
        
        //设置代理,把导演的后期制作代理设置成这个'小花蝴蝶',以后印海报那些事就交给小花蝴蝶干.
        /*
         我们在代码里面常见的那种写法
          XXX.delegate=self;
        或  
         
         XXX.delegate=yyy;
         与下面其实是一个意思.
         
         */
        
        oneDirector.backAssistant = oneGirl;    //把这个女孩指定为导演的那些干杂事的代理.
        
        [oneDirector introMyself];          //导演再次描述自己,backAssistant已经有人了.
        
        [oneDirector.backAssistant posterMake]; //导演可以让自己的backAssistant 去弄海报这事了.
        
    }

     

    4:使用Cordova进行iOS开发知识

    使用Cordova进行iOS开发 (环境配置及基本用法) :http://www.jianshu.com/p/d24219c008b6

    使用Cordova进行iOS开发 (第三方插件的使用:Camera插件):http://www.jianshu.com/p/1e3d0c915dbc

    使用Cordova进行iOS开发 (已存的项目中添加Cordova及自定义插件):http://www.jianshu.com/p/e982b9a85ae8 

    Cordova插件开发入门(IOS版OC跟JS交互):http://my.oschina.net/crazymus/blog/516388

    浅析 Cordova for iOS(OC跟JS交互的说明):http://www.cocoachina.com/industry/20130520/6238.html

    注意:在较新的版本,如果生成的项目没有改变时,路径只要输入引入插件指令,会把OC代码跟XML配置都已经更新好了,上面第二个文章很多步骤都可以省略;

    定位插件:

    进入到目录后在终端命令输入(引入定位插件):

    cordova plugin add cordova-plugin-geolocation

    修改index.html代码:

    <!DOCTYPE html>
    <html>
        <head>
            <title>Capture Photo</title>
            <meta http-equiv="Content-type" content="text/html; charset=utf-8">
            <script type="text/javascript" charset="utf-8" src="cordova.js"></script>
            <script type="text/javascript" charset="utf-8">
     
                document.addEventListener("deviceready",onDeviceReady,false);
     
                //Cordova加载完成会触发
                function onDeviceReady() {
                }
     
                function getCurrentPosition(){
                    //定位数据获取成功响应
                    var onSuccess = function(position) {
                        alert('纬度: '          + position.coords.latitude          + '
    ' +
                              '经度: '         + position.coords.longitude         + '
    ' +
                              '海拔: '          + position.coords.altitude          + '
    ' +
                              '水平精度: '          + position.coords.accuracy          + '
    ' +
                              '垂直精度: ' + position.coords.altitudeAccuracy  + '
    ' +
                              '方向: '           + position.coords.heading           + '
    ' +
                              '速度: '             + position.coords.speed             + '
    ' +
                              '时间戳: '         + position.timestamp                + '
    ');
                    };
     
                    //定位数据获取失败响应
                    function onError(error) {
                        alert('code: '    + error.code    + '
    ' +
                              'message: ' + error.message + '
    ');
                    }
     
                    //开始获取定位数据
                    navigator.geolocation.getCurrentPosition(onSuccess, onError);
                }
            </script>
        </head>
        <body style="padding-top:50px">
            <button style="font-size:23px;" onclick="getCurrentPosition();">获取位置信息</button>
        </body>
    </html>

     

  • 相关阅读:
    python 的基础 学习 第六天 基础数据类型的操作方法 字典
    python 的基础 学习 第五天 基础数据类型的操作方法
    python 的基础 学习 第四天 基础数据类型
    ASP.NET MVC 入门8、ModelState与数据验证
    ASP.NET MVC 入门7、Hellper与数据的提交与绑定
    ASP.NET MVC 入门6、TempData
    ASP.NET MVC 入门5、View与ViewData
    ASP.NET MVC 入门4、Controller与Action
    ASP.NET MVC 入门3、Routing
    ASP.NET MVC 入门2、项目的目录结构与核心的DLL
  • 原文地址:https://www.cnblogs.com/wujy/p/5629736.html
Copyright © 2011-2022 走看看