首页 > 代码库 > 分享一下自己ios开发笔记

分享一下自己ios开发笔记


// ********************** 推断数组元素是否为空 **********************

NSString *element = [array objectAtIndex:2];

if ((NSNull *)element == [NSNull null]) {

}

今天做项目的时候就遇到。要推断数组元素是否为空,我的下面写法,都无效

if(!element)

if([element length]>0)

if(element== NULL)

if(element == Nil)

// **********************  托付的格式 **********************

1 定义协议

@protocol uploadUserInfoDelegate <NSObject>

@required

-(void)uploadCallBack:(NSInteger )code msg:(NSString *)msg;

@end

2 定义托付属性

@property (nonatomic, weak) id<uploadUserInfoDelegate> delegate;

3 调用

if ([self.delegate respondsToSelector:@selector(uploadCallBack:msg:)]) {

[self.delegate uploadCallBack:111 msg:@"mmm"];

}


4 实现方遵循协议传递托付对象实现协议方法

@interface ViewController () <uploadUserInfoDelegate>

obj.delegate = self;

-(void)uploadCallBack:(NSInteger )code msg:(NSString *)msg;


// **********************  block格式 **********************

1. 直接定义成属性

@property (copy, nonatomic) void (^submitUserInfoBlock)(NSString* gender, NSInteger age, NSString* hobbys);

2. typedef定义成类型 方便传參

typedef void (^Callback)(NSInteger code, NSString* msg);

- (void)uploadUserInfoWith:(NSString*)name callBack:(Callback) callback;

3. typedef 定义类型 再合成属性

typedef void(^headerInputBlock)(NSString *inputStr);

@property(nonatomic,copy)headerInputBlock inputBlock;

4. 直接定义Block形參

- (AFHTTPRequestOperation *)httpGetWithMethodName:(NSString *) methodName

param:(id)parameters

response:(void (^)(id dict,NSError *error))callback;


// **********************  创建单例 **********************

+ (ViewController *)shared

{

static ViewController* instance;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

instance = [[ViewController alloc] init];

});

return instance;

}


// **********************  block 中的weakself **********************

block对于其变量都会形成strong reference。对于self也会形成strong reference,而假设self本身对block也是 strong reference的话,就会形成 strong reference循环,造成内存泄露。为了防止这样的情况发生。在block外部应该创建一个week__block reference

所以在block内假设有self的话,一般都会在block外面加一句_block typeof(self)weakself = self;

__block typeof(self) weakself = self;

[self methodThatTakesABlock:^ {

[weakself doSomething];

}

// ********************** 类别的使用category能够扩展系统类和自己定义类**********************

1. 新建类别文件NSString+Util

2.加入方法

@interface NSString (Util)


- (void)hello;

+ (void) say;


@end


3.实现方法

#import "NSString+Util.h"

@implementation NSString (Util)


- (void)hello {

NSLog(@"hello");

}


+ (void)say {

NSLog(@"static say.");

}


@end


4.在其他类中导入并调用


#import "NSString+Util.h"

NSString* mm =  @"aa";

[mm hello];

[NSString say];


// *****************************   获取系统时间的时分秒    *****************************

NSDate *now = [[NSDate alloc] init];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

//设定时间格式,这里能够设置成自己须要的格式

[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

NSString* dateString =  [dateFormatter stringFromDate:now];



// *****************************   定义宏weakSelf    *****************************

#define WS(weakSelf)  __weak __typeof(&*self)weakSelf = self;



// *****************************   ViewController的代码分组    *****************************

#pragma mark - Getters and Setters

#pragma mark - Init and Dealloc

#pragma mark - ViewController Lifecycle

#pragma mark - UITableViewDataSource

#pragma mark - UITableViewDelegate

#pragma mark - CustomDelegate

#pragma mark - Custom View

#pragma mark - View Event

#pragma mark -  Event Response

#pragma mark - GestureRecognizer

#pragma mark - Private Methods



// *****************************   xcode 实用的 tips    *****************************

//  TODO: 推断登陆状态,假设没有登录,显示登录界面。

//  FIXME: 推断登陆状态,假设没有登录,显示登录界面

//  ???: How does this work?

// !!!: Verify that all objects are accounted for

#warning This selector will not fire unless…


// *****************************   xcode @synthesize什么时候不自己主动合成    *****************************

同一时候重写了settergetter

重写了仅仅读属性的getter

使用了@dynamic

@protocol 中定义的全部属性

category 中定义的全部属性

重载的属性

除了后三条,对其它几个我们能够总结出一个规律:当你想手动管理@property的全部内容时,你就会尝试通过实现@property的全部存取方法the accessor methods)或者使用@dynamic来达到这个目的。这时编译器就会觉得你打算手动管理@property,于是编译器就禁用了autosynthesis(自己主动合成)

当你同一时候重写了settergetter时,系统就不会生成ivar(实例变量/成员变量)。这时候有两种选择:

1.手动创建ivar

2.使用@synthesize foo = _foo;,关联@propertyivar



// *****************************   UIToolBar   *****************************

1.工具栏UIToolBar管理了一组UIBarButtonItem

UIBarButtonItem不能任意摆放在屏幕上,它不是继承自UIView

它由导航栏,标签栏或工具栏管理。

栏button条目UIBarButtonItem存储工具栏和导航栏的button的属性。它本身不是button。


2. UIBarButtonItem有两种类型:button元素。空白元素。

UIBarButtonSystemItem枚举表示着不同的系统预设UIBarButtonItem;

UIBarButtonSystemItemFixedSpace类型表示一段空白,须要设置它的宽度值;能够使用它替换须要隐藏的项,以保持位置不变;

UIToolBar开头和末尾加入UIBarButtonSystemItemFlexibleSpace会使其他项有不同有水平对齐方式;

3.

初始化一个用于控制间距的UIBarButtonItem实例negativeSpacer,并设置negativeSpacerwidth属性的值。设为-5的时候。正好能够使button与屏幕边界值为0

UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc]

initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace

target:nil action:nil];

/**

*  width为负数时,相当于btn向右移动width数值个像素,因为button本身和边界间距为5pix。所以width设为-5时,间距正好调整

0width为正数时,正好相反,相当于往左移动width数值个像素

*/

negativeSpacer.width = -5; 


leftItemsSupplementBackButton 设置是否仅仅显示你自己定义的Backbuttuon默认NO显示自己定义的


// *****************************   Category   *****************************

、实现类别


同实现类相似,实现方法就可以


2类别的局限性


1.类别不能加入新的实例变量


2.命名冲突。假设类别中方法和类中已有方法同名,则类别具有更高优先级


3 类别的作用


1.将类的实现分散到多个不同文件或多个不同框架中


2.创建私有方法的前向引用


3.向对象加入非正式协议


4 利用类别分散实现


利用类别能够将类的方法分散到多个源文件里


特别指出的是:类别能够訪问其继承的类的实例变量


在使用一个方法时,对象的方法是在接口中声明、父类中声明、还是类别中声明并不重要


类别不仅能够分散实现到不同源文件,也可跨框架


5使用类别创建前向引用


尽管能够实现未声明的方法,可是编译器会提出警告


通过类别能够提供声明。并且,声明的方法不必要一定在类别的实现中实现,也能够在类的实现中实现


6非正式协议和托付类别


托付(delegage)是一种对象。还有一个类的对象会要求托付对象运行它的某些操作


托付对象接受其他对象对它的特定方法的调用


事实上就是托付对象必须实现别的对象调用的方法,与接口类似


7 ITunesFinder项目


8 、托付和类别


托付和类别有什么关系?托付强调类别的还有一种应用:被发送给托付对象的方法能够声明为一个NSObject的类别


创建一个NSObject的类别称为创建一个非正式协议


9响应选择器


选择器仅仅是一个方法名称,能够使用@selector()预编译指令指定选择器,当中方法名位于圆括号里,但它以OC执行时使用的特殊方式编码,以高速执行查询


NSObject提供了一个respondsToSelector的方法,询问对象以确定其是否实现某个特定消息


10选择器的其它应用


选择器能够被传递,能够作为方法參数。甚至能够作为实例变量存储



// *****************************   NSIndexPath   *****************************

1. indexPath.row 适用TableView

2. indexPath.item 适用于CollectionView

3. 设置UITableViewStyleGrouped能够让headerfootertableview一起滚动


// *****************************   navigationBar and  navigationItem    *****************************

self.navigationItem.leftBarButtonItem = nil;    //隐藏导航栏回退item

self.navigationController.navigationBar.hidden = YES;   //隐藏整个导航栏

// *****************************   Masonry    *****************************

Masonry             NSAutoLayout                   说明

left                NSLayoutAttributeLeft          左側

top                 NSLayoutAttributeTop           上側

right               NSLayoutAttributeRight         右側

bottom              NSLayoutAttributeBottom        下側

leading             NSLayoutAttributeLeading       首部

trailing            NSLayoutAttributeTrailing      尾部

width               NSLayoutAttributeWidth         

height              NSLayoutAttributeHeight        

centerX             NSLayoutAttributeCenterX       横向中点

centerY             NSLayoutAttributeCenterY       纵向中点

baseline            NSLayoutAttributeBaseline      文本基线


// *****************************   instancetype - id    *****************************

instancetype能够返回和方法所在类同样类型的对象。id仅仅能返回未知类型的对象;

instancetype仅仅能作为返回值,不能像id那样作为參数



// *****************************   tableView 动态Cell    *****************************

{

    BOOL cellIsSelected;

    NSIndexPath* _indexPath;

}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{


UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];


if ([cell isSelected] && cellIsSelected == NO) {

cellIsSelected = YES;

_indexPath = indexPath;

} else {

cellIsSelected = NO;

}



[tableView beginUpdates];

[tableView endUpdates];


}


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {


if(cellIsSelected && _indexPath.row == indexPath.row) {

return 50 * 2.0;

}

return 50;

}


// *****************************  ios 异常崩溃处理    *****************************


使用第三方库 UncaughtExceptionHandler

能够检測出常见错误,并友好的提示用户 比如


1.NSArrayNSDictionaryNSStringKVC等问题引起的闪退。

2.解决NSObject performSelector找不到selector引起的闪退。


用法:

1、首先须要在appDelegate中使用InstallUncaughtExceptionHandler()用于监听

2、加入UncaughtExceptionHandler这个类


iOS SDK提供的函数是NSSetUncaughtExceptionHandler来进行异常处理。可是无法处理内存訪问错误、反复释放等错误,由于这些错误发送的SIGNAL。所以须要处理这些SIGNAL


4. SignalHandler不要在debug环境下測试。由于系统的debug会优先去拦截。

我们要执行一次后,关闭debug状态。应该直接在模拟器上点击我们build上去的app去执行。而UncaughtExceptionHandler能够在调试状态下捕捉



// *****************************  指针和引用的差别   *****************************

1. 引用在语言内部用指针实现(怎样实现?)。

2. 对一般应用而言。把引用理解为指针,不会犯严重语义错误。

3. 引用是操作受限了的指针(仅容许取内容操作)



// *****************************  iOS 集合的深复制与浅复制   *****************************

1. 在非集合类对象中:对immutable对象进行copy操作,是指针复制,mutableCopy操作时内容复制;对mutable对象进行copymutableCopy都是内容复制。

用代码简单表演示样例如以下:


[immutableObject copy] // 浅复制

[immutableObject mutableCopy] //深复制

[mutableObject copy] //深复制

[mutableObject mutableCopy] //深复制


2. 在集合类对象中,对immutable对象进行copy,是指针复制,mutableCopy是内容复制;对mutable对象进行copymutableCopy都是内容复制。可是:集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制。

用代码简单表演示样例如以下:


[immutableObject copy] // 浅复制

[immutableObject mutableCopy] //单层深复制

[mutableObject copy] //单层深复制

[mutableObject mutableCopy] //单层深复制


// **********  ios目录:Documents, Library tmpLibrary包括CachesPreferences文件夹 **************

Documents:苹果建议将程序创建产生的文件以及应用浏览产生的文件数据保存在该文件夹下。iTunes备份和恢复的时候会包含此文件夹

Library:存储程序的默认设置或其他状态信息。

Library/Caches:存放缓存文件,保存应用的持久化数据,用于应用升级或者应用关闭后的数据保存。不会被itunes同步,所以为了降低同步的时间,能够考虑将一些比較大的文件而又不须要备份的文件放到这个文件夹下。

tmp:提供一个即时创建暂时文件的地方。但不须要持久化。在应用关闭后,该文件夹下的数据将删除,也可能系统在程序不执行的时候清除。


1Documents文件夹


  您应该将全部的应用程序数据文件写入到这个文件夹下。

  这个文件夹用于存储用户数据或其他应该定期备份的信息。

  保存由应用程序产生的文件或者数据,比如:涂鸦程序生成的图片,游戏关卡记录

  iCloud会自己主动备份Document中的全部文件。

  上架注意 假设保存了从网络上下载的文件,在上架审批的时候会被拒!


2AppName.app文件夹:这是应用程序的程序包文件夹,包括应用程序的本身。

因为应用程序必须经过签名,所以您在执行时不能对这个文件夹中的内容进行改动。否则可能会使应用程序无法启动。


3Library文件夹:这个文件夹下有两个子文件夹:Caches Preferences


  Preferences 文件夹:包括应用程序的偏好设置文件。

您不应该直接创建偏好设置文件。而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.


    系统偏好,用户偏好。通过[NSUserDefaults standarDefaults]来直接操作


  Caches 文件夹:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中须要的信息。

    缓存。保存网络下载的文件。兴许仍然须要继续使用。比如:网络下载的离线数据

    缓存文件夹中的文件系统不会自己主动删除,可做离线訪问

    程序必须要提供一个完好的清除缓存文件夹的解决方式


4tmp文件夹:用于存放暂时文件(暂时数据),保存应用程序再次启动过程中不须要的信息。

  暂时文件,保存在tmp中的文件,系统会自己主动回收,譬如磁盘空间紧张、又一次启动手机、应用退出后删除

  程序猿不须要管tmp目录的释放



// *****************************  UIApplication  openURL  *****************************

1.设置icon上的数字图标

//设置主界面icon上的数字图标。在2.0中引进,缺省为0

[UIApplicationsharedApplication].applicationIconBadgeNumber = 4;

2.设置摇动手势的时候。是否支持redo,undo操作

//摇动手势。是否支持redo undo操作。

//3.0以后引进,缺省YES

[UIApplicationsharedApplication].applicationSupportsShakeToEdit =YES;


3.推断程序执行状态

//推断程序执行状态,在2.0以后引入

/*

UIApplicationStateActive,

UIApplicationStateInactive,

UIApplicationStateBackground

*/

if([UIApplicationsharedApplication].applicationState ==UIApplicationStateInactive){

NSLog(@"程序在执行状态");

}


4.阻止屏幕变暗进入休眠状态

//阻止屏幕变暗。谨慎使用,缺省为no 2.0

[UIApplicationsharedApplication].idleTimerDisabled =YES;

谨慎使用本功能。由于很耗电。

5.显示联网状态

//显示联网标记 2.0

[UIApplicationsharedApplication].networkActivityIndicatorVisible =YES;


6.map上显示一个地址

NSString* addressText =@"1 Infinite Loop, Cupertino, CA 95014";

// URL encode the spaces

addressText =  [addressTextstringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

NSString* urlText = [NSStringstringWithFormat:@"http://maps.google.com/maps?q=%@", addressText];


[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:urlText]];


7.发送电子邮件

NSString *recipients =@"mailto:first@example.com?cc=second@example.com,third@example.com&subject=Hello from California!";

NSString *body =@"&body=It is raining in sunny California!";


NSString *email = [NSStringstringWithFormat:@"%@%@", recipients, body];

email = [emailstringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];


[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:email]];


8.打电话到一个号码


// Call Google 411

[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"tel://8004664411"]];

9.发送短信

// Text to Google SMS

[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"sms://466453"]];

10.打开一个网址


// Lanuch any iPhone developers fav site

[[UIApplicationsharedApplication]openURL:[NSURLURLWithString:@"http://itunesconnect.apple.com"]];





// *****************************  AFNetWorking https SSL认证   *****************************






// *****************************  ios File IO *******************************


数组、字典仅仅能将BOOLNSNumberNSStringNSDataNSDateNSArrayNSDictionary写入属性列表plist文件

NSFileHandle类主要对文件内容进行读取和写入操作

NSFileManager类主要对文件的操作(删除、改动、移动、复制等等)



// *****************************  载入本地html *******************************


- (void)loadExamplePage:(UIWebView*)webView {

NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];

NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil];

NSURL *baseURL = [NSURL fileURLWithPath:htmlPath];

[webView loadHTMLString:appHtml baseURL:baseURL];

}



- (void)loadDocument:(NSString*)docName {

NSString* path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"html"];

NSURL *url = [NSURL fileURLWithPath:path];

NSURLRequest *request = [NSURLRequest requestWithURL:url];

self.webView.scalesPageToFit = YES;

[self.webView loadRequest:request];

}


// *****************************  UIScrollView里面嵌套UITableView这样的结构是否合理? *******************************

Q: 类似网易新闻和lofter这样的多标签滚动切换的效果,我以为是在scrollview上加入tableview来实现的,但这样实现感觉会导致ViewController臃肿不堪,实现delegatedatasource也比較混乱;想听听大家对于架构这样的界面有什么样的建议,能提高代码的复用还有把代码剥离放到合适的地方;真的好想写出结构清晰美观的代码啊思密达!


A: 每一个标签相应的列表能够是一个viewController。它负责这个列表的内容和一切的交互。

scrollView里装的是viewController.view

scrollView所在的viewController能够称之为containerViewController,实际上起到了NavigationController之类的容器作用。而详细的内容。能够称之为contentViewController

它的优点:


同一个contentVC能够在不同的容器中自由地拆下和装上。减少耦合,或者如题主所说能提高代码的复用还有把代码剥离放到合适的地方

能够做到动态地调整contentVC的数量,样式也能够各不同样,仅仅要是vc就可以。题主图中的网易新闻无疑是这么做的佼佼者

能够通过两块木板过河这种原理。使用三个view来作为contentVCscrollView的中间层。做到不论有多少个contentVC(比方网易新闻中加入非常多标签),同一时候载入在scrollView上的都仅仅有3

肯定还有,我一时没想到。

。。

总的来说,这样的结构能够称得上清晰美观,但也要看实现者的水准,做得不好反而会带来非常多问题。做得好的。。。你看网易新闻多好用:)





/*************************** 动态口令 ****************************/

每次认证时令牌与server分别依据相同的密钥。相同的随机数和相同的算法计算出认证时的动态口令,


动态password的password事实上不是随机的,而是由规律的。当下动态password分为两类,时间性和事件性。何为时间性动态password?该类令牌产出动态password是以时间为參数的。而事件性一般以使用次数为參数的。我们以时间性动态为主要说明对象。整个验证的步骤例如以下:


1.动态password令牌产生动态password以时间和种子为參数,进行迭代,得出动态password,这里的时间通常是秒数。

每一个时间性动态password令牌中会内置一个时钟芯片。

2.server校验动态password。server读取系统时间加上种子。以同样的迭代方法得出动态password,然后两方进行比对。

说到这边。可能有所怀疑难道令牌的时间和server的时间一定会一致吗?我的答案肯定是不一致的。那怎么能检验的过去呢?原来非常easy,server校验是是在一个时间区间里校验的,比方如今是1200,server会生成1155-1205中全部的动态password,然后和令牌产生的动态password比对。这样不就攻克了时间不一致的问题了。另外server会把令牌和server相差的时间记录下来,下次检验的会先把这个偏移值记录下来,以降低动态password迭代次数,这样就完毕了另外一个比較重要的功能,偏移值自己主动调整。




显示Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles  YES

隐藏Mac隐藏文件的命令:defaults write com.apple.finder AppleShowAllFiles  NO

输完单击Enter键,退出终端。又一次启动Finder就能够了

重新启动Finder:鼠标单击窗体左上角的苹果标志-->强制退出-->Finder-->又一次启动





/*************************** title使用self.navigationItem.title ****************************/

Q:楼主有没有试过,在ViewDidLoad方法中,对self.titleself.navigationItem.title分别进行设置,出现的效果是一样的?

A: 设置self.title会设置导航title,可是假设以下有tabBar,也会设置tabBarItemtitle,所以还是单独设置好一些,导航title使用self.navigationItem.title


/*************************** iOS6以后UILabel显示不同的字体和颜色 ****************************/


NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"Using NSAttributed String"];

[str addAttribute:NSForegroundColorAttributeName value:[UIColor blueColor] range:NSMakeRange(0,5)];

[str addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(6,12)];

[str addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(19,6)];

[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Arial-BoldItalicMT" size:30.0] range:NSMakeRange(0, 5)];

[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue-Bold" size:10.0] range:NSMakeRange(6, 12)];

[str addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"Courier-BoldOblique" size:30.0] range:NSMakeRange(19, 6)];

self.attrLabel.attributedText = str;





/*************************** xcode中的project.pbxproj冲突怎么解决 ****************************/

1 加入或修改文件布局时先更新,改完后要马上提交,团队成员都遵照这个约定。

/*************************** translucent  IOS7 导航栏是否是半透明设置,子视图是否从屏幕 0, 0開始 ****************************/

self.navigationController.navigationBar.translucent = NO;


/*************************** 保持程序在后台长时间执行 ****************************/

iOS上的VOIP程序是肯定能后台监測到来电并提示用户的

VOIPSIP报文走的是TCP通道,而语音报文走的是UDP通道。

iOS平台中。NSStream即为TCP,而且NSStream有一个VOIP属性,假设设置了,那么你的程序处于后台时候,系统会托管你这个NSStream通道。并保持和server连接的畅通,假设这个时候server通过这个NSSreamTCP socket)给client发送了数据,系统会激活你处于后台的程序执行10秒钟已处理这个报文,你能够在这个时候通过LocalNotification来提示用户有来电。



/*************************** 动态计算文字的高度 ****************************/

NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:16.0]}


CGSize size = [content boundingRectWithSize:CGSizeMake(UI_SCREEN_WIDTH, CGFLOAT_MAX) o

ptions: NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size;


/*************************** 打开其他app ****************************/

使用[[UIApplication sharedApplication] canOpenURL:instagramURL];来推断是否已安装该APP,

使用[[UIApplication sharedApplication] openURL:fansPageURL];来打开该APP,若未安装,则默认在safari中打开对应页面.


1. source app

NSURL *sourcePageURL;

sourcePageURL = [NSURL URLWithString:[NSString stringWithFormat:@"joejoe://%@", @"aaa"]]; //不能有空格

[[UIApplication sharedApplication] openURL:sourcePageURL];


2.target app

2.1 taget->info->URL Types->URL Schemes设置namembc2m

// 获取发送过来的值

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation

{

    NSString* str =  [[url host] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

}


/**************************** 模拟用户触发事件 **************************/

UIControl有一个sendActionsForControlEvents消息,能够使用它手动触发控件事件:

[button sendActionsForControlEvents:UIControlEventTouchUpInside]

[button sendAction:<#(nonnull SEL)#> to:<#(nullable id)#> forEvent:<#(nullable UIEvent *)#>]




/********************* 编码问题导致NSURL初始化一直为null的解决的方法设置utf8编码 **********************/

NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];


/********************* NSDictionaryjson str **********************/

- (NSString *)toJSONorNSString:(id )o

{


NSData *data=http://www.mamicode.com/[NSJSONSerialization dataWithJSONObject:o options:NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments error:nil];


if (data =http://www.mamicode.com/= nil) {


return nil;

}



NSString *str=[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];


return str;

}




/*****************************     MVVM      ******************************/

MVC的基础上。把C拆出一个ViewModel专门负责数据处理的事情。就是MVVM。然后,为了让ViewViewModel之间可以有比較松散的绑定关系,于是我们使用ReactiveCocoa。由于苹果本身并没有提供一个比較适合这样的情况的绑定方法。iOS领域里KVONotificationblockdelegatetarget-action都可以用来做数据通信。从而来实现绑定。但都不如ReactiveCocoa提供的RACSignal来的优雅。假设不用ReactiveCocoa,绑定关系可能就做不到那么松散那么好。但并不影响它还是MVVM



/*****************************    数组不转化成实体类的优点     ******************************/

数组内容的转化成本较高:数组里面每项都要转化成Item对象,假设Item对象中还有类似数组,就非常头疼。

转化之后的数据在大部分情况是不能直接被展示的。为了可以被展示,还须要第二次转化。

仅仅有在API返回的数据高度标准化时,这些对象原型(Item)的可复用程度才高,否则easy出现类型爆炸。提高维护成本。

调试时通过对象原型查看数据内容不如直接通过NSDictionary/NSArray直观。

同一API的数据被不同View展示时,难以控制数据转化的代码,它们有可能会散落在不论什么须要的地方。

分享一下自己ios开发笔记