Xcode 7中http通信错误

  • 错误:
    Xcode 7中http通信出现如下错误:Application Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

  • 原因:在iOS9中,苹果将原http协议改成了https协议,使用 TLS1.2 SSL加密请求数据

  • 解决方法 编辑 info.plist,加入如下设置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      <plist>
    <dict>
    ....
    <key>NSAppTransportSecurity</key>
    <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    </dict>
    </dict>
    </plist>

assign、retain、copy举例解释

NSString *pt = [[NSString alloc] initWithString:@”abc”];

上面一段代码会执行以下两个动作

  1. 在堆上分配一段内存用来存储@”abc” 比如:内存地址为:0x1111 内容为 “abc”
  2. 在栈上分配一段内存用来存储pt 比如:地址为:0xAAAA 内容自然为0x1111

下面分别看下assign retain copy

1
2
3
assign的情况:NSString *newPt = [pt assing];   
此时newPt和pt完全相同 地址都是0xAAAA内容为0x1111即newPt只是pt的别名,
对任何一个操作就等于对另一个操作。 因此retainCount不需要增加。
1
2
3
retain的情况:NSString *newPt = [pt retain];   
此时newPt的地址不再为0xAAAA,可能为0xAABB 但是内容依然为0x1111。
因此newPt 和 pt 都可以管理"abc"所在的内存。因此 retainCount需要增加1
1
2
3
copy的情况:NSString *newPt = [pt copy]; 
此时会在堆上重新开辟一段内存存放@"abc" 比如0x1122 内容为@"abc
同时会在栈上为newPt分配空间 比如地址:0xAACC 内容为0x1122 因此retainCount增加1供newPt来管理0x1122这段内存

nonatomic

禁止多线程,变量保护,提高性能

1
2
3
atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,
造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,
如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

1
2
3
4
指出访问器不是原子操作,而默认地,访问器是原子操作。这也就是说,在多线程环境下,解析的访问器提供一个对属性的安全访问,
从获取器得到的返回值或者通过设置器设置的值可以一次完成,即便是别的线程也正在对其进行访问。
如果你不指定 nonatomic,在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,
如果指定了nonatomic,那么访问器只是简单地返回这个值

iOS程序启动原理

UIApplicationMain

main函数中执行了一个UIApplicationMain这个函数

1
2
int UIApplicationMain(int argc, char *argv[], NSString *principalClassName,
NSString *delegateClassName);

  • argc、argv:直接传递给UIApplicationMain进行相关处理即可

  • principalClassName:指定应用程序类名(app的象征),该类必须是UIApplication(或子类)。如果为nil,则用UIApplication类作为默认值

  • delegateClassName:指定应用程序的代理类,该类必须遵守UIApplicationDelegate协议

  • UIApplicationMain函数会根据principalClassName创建UIApplication对象,根据delegateClassName创建一个delegate对象,并将该delegate对象赋值给UIApplication对象中的delegate属性

接着会建立应用程序的Main Runloop(事件循环),进行事件的处理(首先会在程序完毕后调用delegate对象的application:didFinishLaunchingWithOptions:方法)
程序正常退出时UIApplicationMain函数才返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import <UIKit/UIKit.h>

#import "YYAppDelegate.h"

int main(int argc, char * argv[])
{
@autoreleasepool {

/*
argc: 系统或者用户传入的参数个数
argv: 系统或者用户传入的实际参数
1.根据传入的第三个参数创建UIApplication对象
2.根据传入的第四个产生创建UIApplication对象的代理
3.设置刚刚创建出来的代理对象为UIApplication的代理
4.开启一个事件循环(可以理解为里面是一个死循环)这个时间循环是一个队列(先进先出)先添加进去的先处理
*/
return UIApplicationMain(argc, argv, @"UIApplication", @"YYAppDelegate");
}
}

ios程序启动原理
ios程序启动原理

程序启动的完整过程

main函数

….

UIApplicationMain

  • 创建UIApplication对象

  • 创建UIApplication的delegate对象

delegate对象开始处理(监听)系统事件(没有storyboard)

  • 程序启动完毕的时候, 就会调用代理的application:didFinishLaunchingWithOptions:方法
  • 在application:didFinishLaunchingWithOptions:中创建UIWindow
  • 创建和设置UIWindow的rootViewController
  • 显示窗口

根据Info.plist获得最主要storyboard的文件名,加载最主要的storyboard(有storyboard)

  • 创建UIWindow
  • 创建和设置UIWindow的rootViewController
  • 显示窗口

copy与retain

  • copy:建立一个索引计数为1的对象,然后释放旧对象对NSString
    对NSString 它指出,在赋值时使用传入值的一份拷贝。拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议的对象类型有效。
  • retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1
    对其他NSObject和其子类对参数进行release旧值,再retain新值
    指定retain会在赋值时唤醒传入值的retain消息。此属性只能用于Objective-C对象类型,而不能用于CoreFoundation对象。(原因很明显,retain会增加对象的引用计数,而基本数据类型或者CoreFoundation对象都没有引用计数——译者注)。
    注意: 把对象添加到数组中时,引用计数将增加对象的引用次数+1

retain的实际语法为

1
2
3
4
5
6
7
-(void)setName:(NSString *)newName { 
if (name != newName) {
[name release];
name = [newName retain];
// name’s retain count has been bumped up by 1
}
}
  • copy与retain
    Copy其实是建立了一个相同的对象,而retain不是:比如一个NSString对象,地址为0×1111,内容为@”STR”Copy到另外一个NSString之后,地址为0×2222,内容相同,新的对象retain为1,旧有对象没有变化
    retain到另外一个NSString之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1
    也就是说,retain是指针拷贝,copy是内容拷贝。哇,比想象的简单多了…
    retain的set方法应该是浅复制,copy的set方法应该是深复制了

  • copy另一个用法
    copy是内容的拷贝 ,对于像NSString,的确是这样.
    但是,如果是copy的是一个NSArray呢?比如,
    NSArray array = [NSArray arrayWithObjects:@”hello”,@”world”,@”baby”];
    NSArray
    array2 = [array copy];
    这个时候,,系统的确是为array2开辟了一块内存空间,但是我们要认识到的是,array2中的每个元素,,只是copy了指向array中相对应元素的指针.这便是所谓的”浅复制”.

oc 关键字复习

  • #synthesize关键字:根据@property设置,自动生成成员变量相应的存取方法,从而可以使用点操作符来方便的存取该成员变量 。
  • self 关键字 :类似于java中的this,是隐藏参数,指向当前调用方法的类
  • NSObject是大多数对象都会用到的内存管理,和初始化框架,以及反射和类型操作. 相 当于Object。
  • NS是NextSTEP缩写,表示这个函数来自Cocoa工具包。
  • -减号是实例方法, + 是类方法
  • 使用@property配合@synthesize可以让编译器自动实现getter/setter方法,使用的时候也很方便,可以直接使用“对象.属性”的方法调用;如果我们想要”对象.方法“的方式来调用一个方法并获取到方法的返回值,那就需要使用@property配合@dynamic了
  • 使用@dynamic关键字是告诉编译器由我们自己来实现访问方法。如果使用的是@synthesize,那么这个工作编译器就会帮你实现了
  • readonly此标记说明属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器。或者如果你使用@synthesize关键字,也是有读取器方法被解析。而且如果你试图使用点操作符为属性赋值,你将得到一个编译错误。
  • readwrite此标记说明属性会被当成读写的,这也是默认属性。设置器和读取器都需要在@implementation中实现。如果使用@synthesize关键字,读取器和设置器都会被解析。
  • nonatomic:非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问。
    atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。