1.使用pch文件
2.在info.plist中配置URL Schemes
3.plist配置拍照界面,复制,粘贴等菜单的显示语言 显示中文
4.使用非ARC库/ARC库
5.链接选项-Objc & -all_load & -force_load
6.assign, retain,weak,strong,readwrite,readonly,copy,nonatomic,atomic属性设置
7.结构体与类的区别
8.栈和堆
9.工程Target支持Xcode最低版本
10.设置工程是否支持ARC
pch文件可以用来存储共享信息
*存放一些全局的宏(整个项目中都用的上的宏)
*用来包含一些全部的头文件(整个项目中都用得上的头文件)
*能自动打开或者关闭日志输出功能
Xcode6以前会自动创建pch文件,新版本要自己手动创建,下图是Xcode7的
然后在工程的targets里面的Building Setting中将Precompile Prefix Header右边的NO改为Yes
然后在Precompile Prefix Header下边的Prefix Header右边双击,添加刚刚创建的pch文件的工程路径,添加格式:“$(SRCROOT)/pch文件在工程下的路径/pch文件名” ,$(SRCROOT)的意思就是工程根目录的意思。如果还不太清楚的话可以右键pch文件,然后show in finder。(我用的:$(SRCROOT)/MyIM/CustomShared.pch)
在info.plist中配置URL Schemes
//该方法在app还未被杀掉会进入这个
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
//传过来请求串
NSString *text=[[url host] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSetURLQueryAllowedCharacterSet]];
UIAlertController *alert=[UIAlertController alertControllerWithTitle:@"打卡"message:text preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancel=[UIAlertAction actionWithTitle:@"取消"style:UIAlertActionStyleCancel handler:nil];
[alert addAction:cancel];
[self.window.rootViewController presentViewController:alert animated:YEScompletion:nil];
return YES;
}
//app被杀掉时在这里可以获取
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//app杀死状态可以此处获取第三方传送过来的信息
if (launchOptions[@"UIApplicationLaunchOptionsURLKey"]) {
//获取登录的参数
NSString *urlStr=launchOptions[@"UIApplicationLaunchOptionsURLKey"];
}
return YES;
}
在Safari中输入测试
vieim://user=123,pwd=456
4.在app中测试,需要添加可信任app
info.plist加入
<key>LSApplicationQueriesSchemes</key>
<array>
<string>urlscheme</string>
<string>urlscheme2</string>
<string>urlscheme3</string>
<string>urlscheme4</string>
</array>
调用
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"URL Scheme://URL identifier"]];
从结果看出app的地址构成是: URL Scheme://URL identifier
myapp://后面的字 可以为点"."和等号"=" 不可以为空格和问号
plist配置拍照界面,复制,粘贴等菜单的显示语言 显示中文
在plist里面Localization native development region 选择 china ,
然后Localized resources can be mixed 选 YES,如果没有Localized resources can be mixed,需手动添加
使用非ARC库/ARC库
选择项目中的Targets,选中你所要操作的Target,
选Build Phases,在其中Complie Sources中选择
-fobjc-arc,
适配非ARC库,在非ARC文件资源添加 -fno-objc-arc 字段适配。
链接选项-Objc & -all_load & -force_load
-ObjC
这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来。这样编译之后的app会变大(因为加载了其他的objc代码进来)。但是如果静态库中有类和category的话只有加入这个flag才行。
-all_load
这个flag是专门处理-ObjC的一个bug的。用了-ObjC以后,如果类库中只有category没有类的时候这些category还是加载不进来。变通方法就是加入-all_load或者-force-load。-all_load会强制链接器把目标文件都加载进来,即使没有objc代码。-force_load在xcode3.2后可用。但是-force_load后面必须跟一个只想静态库的路径
在Xcode4.2之后,这个链接器bug已经被修复,因此-all_load 和 -force_load标志都不再需要了。在必要时添加-ObjC即可。
assign, retain,weak,strong,readwrite,readonly,copy,nonatomic,atomic属性设置
strong,weak
strong与weak是由ARC新引入的对象变量属性
ARC引入了新的对象的新生命周期限定,即零弱引用。如果零弱引用指向的对象被deallocated的话,零弱引用的对象会被自动设置为nil。
@property(strong) MyClass *myObject;
相当于@property(retain) MyClass *myObject;
@property(weak) MyOtherClass *delegate;
相当于@property(assign) MyOtherClass *delegate;
强引用与弱引用的广义区别:
强引用也就是我们通常所讲的引用,其存亡直接决定了所指对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示列表中,则此对象会被从内存中释放。
弱引用除了不决定对象的存亡外,其他与强引用相同。即使一个对象被持有无数个若引用,只要没有强引用指向他,那麽其还是会被清除。没办法,还是 “强哥” 有面子。
retain
setter方法对参数进行 release 旧值再 retain 新值(释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为 1)
简单讲strong等同retain
assign
setter 方法直接赋值,不进行任何 retain 操作,为了解决原类型与环循引用问题(指定setter方法用简单的赋值,这是默认操作。你可以对标量类型(如int)使用这个属性。你可以想象一个float,它不是一个对象,所以它不能retain、copy)。
weak比assign多了一个功能,当对象消失后自动把指针变成nil,好处不言而喻。
系统常量如int,bool等基本数据类型assign
readonly,readwrite
readwrite是变量的默认属性,就是如果你 (readwrite and readonly 都没有使用,那么你的变量就是 readwrite属性 ) ,通过加入 readwrite 属性你的变量就会有 get 和 set 方法。
readonly就是表明变量只有可读方法,也就是说,你只能使用它的 get 方法。
copy
setter 方法进行 Copy 操作,与 retain 处理流程一样,先旧值 release ,再 copy 出新的对象,retainCount 为 1 。这是为了减少对上下文的依赖而引入的机制(copy建立一个索引计数为 1 的对象,然后释放旧对象;retain 释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为 1)
copy 其实是建立了一个相同的对象,而 retain 不是
nonatomic,atomic
atomic:对于对象的默认属性,就是setter/getter生成的方法是一个原子操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行setter全部语句之前,另一个线程开始执行setter的情况,相关于方法头尾加了锁一样但效率相对较低。
nonatomic:不保证setter/getter的原子性,多线程情况下会提高性能但数据可能会有问题
结构体与类的区别
*结构体只能封装属性,而类不仅可以封装属性还可以封装方法
*结构体变量分配在栈空间中,OC对象分配在堆空间中
栈空间相对较小,但是存储在栈中的数据访问效率相对较高
堆空间相对较大,但是存储在堆中的数据访问效率相对较低
*结构体的赋值是直接赋的值(拷贝),而对象的指针赋值是对象的地址
*什么时候使用结构体:封装数据只有属性;属性较少,一般三个及以下(如果定义一个结构体中有很多属性,那么这个时候结构体变量在栈中就会占据很大一块
空间,反而会降低效率)
*什么时候使用类:封装数据既有属性也有行为;只有属性,但是属性较多
栈和堆
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其
操作方式类似于数据结构中的栈。
2、堆区(heap)— 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回
收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的
全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另
一块区域。程序结束后由系统释放。
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。
stack) 是由系统编译器自动管理,不需要程序员手动管理;栈是向低地址扩展的数据结构,是一块连续的内存区域。意思是栈顶上的地址和栈的最大容量是系统预先规定好的,如果申请的空间超过了栈的剩余空间的时候就溢出
堆区(heap) 释放工作由程序员手动管理,不及时回收容易产生内存泄露;堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。
Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,就是release
OC对象存放于堆里面(堆内存要程序员手动回收)
非OC对象一般放在栈里面(栈内存会被系统自动回收)
碎片的问题:
对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存快从栈中弹出。
分配方式:
堆都是动态分配的,没有静态分配的堆。栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配是有alloc函数进行分配的,但是栈的动态分配和堆是不同的,他的动态分配由编译器进行释放,无需我们手工实现。
分配效率:
栈是机器系统提供的数据结构,计算机会在底层堆栈提供支持,分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,他的机制是很复杂的。
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。 使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。栈是吃了吐 ,堆是吃了拉
工程Target支持Xcode最低版本
如下图红框中位置修改
如果工程不能直接打开,就显示xcodeproj文件的包内容,双击project.pbxproj文件打开,修改下面红框版本
设置工程是否支持ARC
Build Settings搜索automatic reference,下图设置为YES就是支持ARC,NO就是不支持