OC笔记 - iOS适配、block内存泄露、电话短信邮件等小功能(2015.3.27)

来源:互联网 发布:中电科大数据院 编辑:程序博客网 时间:2024/06/04 21:46

1.IOS适配问题

    IOS6启动app时launchImage中出现了状态栏,而IOS7并没有出现这种情况。是因为IOS6的View不包含状态栏。在解决这个适配问题中,通常在项目勾选“Hide status bar”隐藏状态栏,然后在application的delegate的didFinishLaunchingWithOptions中用代码设置状态栏可见“application.statusBarHidden =NO;”

 

在代码中可拿到当前设备的版本号,可对此进行判别版本号来做适配

    if ([[UIDevicecurrentDevice].systemVersiondoubleValue] >=7.0){//IOS7以上

}else{//IOS7以下

    }

由于在项目开发时经常做适配,所以应该将上面代码定义成宏抽取到pch文件,适用于全局

例如:#define ios7 ([[UIDevicecurrentDevice].systemVersion doubleValue] >=7.0)

 

 

2.block循环引用引发内存泄露

block是copy属性,强引用。在block中调用self会对控制器进行强引用,导致self指向的控制器无法被释放,于是内存泄露。

所以在block中若需要使用self,需先把self改为若引用。

__unsafe_unretainedNJShareViewController*unsafeSelf = self;

 

    __weakNJShareViewController*unsafeSelf = self;

//   __weak当对象释放之后会自动设置为nil,__unsafe_unretained不会,一般用weak

__weaktypeof(self) unsafeSelf =self;//该代码有扩展性

 

常用小功能

3.打电话

方法1

最简单最直接的方式:直接跳到拨号界面

NSURL *url = [NSURLURLWithString:@"tel://10010"];

[[UIApplicationsharedApplication] openURL:url];

缺点

电话打完后,不会自动回到原应用,直接停留在通话记录界面

 

方法2

拨号之前会弹框询问用户是否拨号,拨完后能自动回到原应用

NSURL *url = [NSURLURLWithString:@"telprompt://10010"];

[[UIApplicationsharedApplication] openURL:url];

缺点

因为是私有API,所以可能不会被审核通过

 

方法3

创建一个UIWebView来加载URL,拨完后能自动回到原应用

if(_webView ==nil){

    _webView = [[UIWebViewalloc]initWithFrame:CGRectZero];

}

[_webViewloadRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"tel://10010"]]];

 

需要注意的是:这个webView千万不要添加到界面上来,不然会挡住其他界面

 

 

4.发短信

方法1

直接跳到发短信界面,但是不能指定短信内容,而且不能自动回到原应用

NSURL *url = [NSURLURLWithString:@"sms://10010"];

[[UIApplicationsharedApplication] openURL:url];

 

方法2

如果想指定短信内容,那就得使用MessageUI框架

包含主头文件

#import <MessageUI/MessageUI.h>

 

显示发短信的控制器

MFMessageComposeViewController *vc = [[MFMessageComposeViewControlleralloc]init];

// 设置短信内容

vc.body =@"吃饭了没?";

// 设置收件人列表

vc.recipients =@[@"10010",@"02010010"];

// 设置代理

vc.messageComposeDelegate=self;

 

// 显示控制器

[selfpresentViewController:vc animated:YES completion:nil];

 

代理方法,当短信界面关闭的时候调用,发完后会自动回到原应用

- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result

{

    // 关闭短信界面

    [controller dismissViewControllerAnimated:YES completion:nil];

   

    if (result ==MessageComposeResultCancelled){

        NSLog(@"取消发送");

    } elseif (result== MessageComposeResultSent) {

        NSLog(@"已经发出");

    } else {

        NSLog(@"发送失败");

    }

}

 

5.发邮件

方法1

用自带的邮件客户端,发完邮件后不会自动回到原应用

NSURL *url = [NSURLURLWithString:@"mailto://10010@qq.com"];

[[UIApplicationsharedApplication] openURL:url];

 

方法2

跟发短信的第2种方法差不多,只不过控制器类名叫做:MFMailComposeViewController

 

邮件发送后的代理方法回调,发完后会自动回到原应用

- (void)mailComposeController:(MFMailComposeViewController *)controllerdidFinishWithResult:(MFMailComposeResult)resulterror:(NSError *)error

{

    // 关闭邮件界面

    [controller dismissViewControllerAnimated:YES completion:nil];

   

    if (result ==MFMailComposeResultCancelled){

        NSLog(@"取消发送");

    } elseif (result== MFMailComposeResultSent) {

        NSLog(@"已经发出");

    } else {

        NSLog(@"发送失败");

    }

}

 

6.打开其他常见文件

如果想打开一些常见文件,比如html、txt、PDF、PPT等,都可以使用UIWebView打开

只需要告诉UIWebView文件的URL即可

至于打开一个远程的共享资源,比如http协议的,也可以调用系统自带的Safari浏览器:

NSURL *url = [NSURLURLWithString:@”http://www.baidu.com"];

[[UIApplicationsharedApplication] openURL:url];

 

7.应用间跳转

有时候,需要在本应用中打开其他应用,比如从A应用中跳转到B应用

 

首先,B应用得有自己的URL地址(在Info.plist中配置)

接着在A应用中使用UIApplication完成跳转

NSURL *url = [NSURLURLWithString:@"abc://ios.app.cn"];

[[UIApplicationsharedApplication] openURL:url];

 

8.应用评分

为了提高应用的用户体验,经常需要邀请用户对应用进行评分

 

应用评分无非就是跳转到AppStore展示自己的应用,然后由用户自己撰写评论

 

如何跳转到AppStore,并且展示自己的应用

方法1

NSString *appid =@"444934666";

NSString *str = [NSStringstringWithFormat:

                 @"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%@",appid];

[[UIApplicationsharedApplication] openURL:[NSURL URLWithString:str]];

 

方法2

NSString *str = [NSStringstringWithFormat:

                 @"itms-apps://itunes.apple.com/cn/app/id%@?mt=8",appid];

[[UIApplicationsharedApplication] openURL:[NSURL URLWithString:str]];

 

9.练习中遇到的问题

往一个有tabBar和navigationBar的控制器的view中拖入一个控件,在IOS7模拟器运行正常,在IOS6位置却有变化。这是因为IOS7默认view的大小为320*480,而IOS6的view默认除去状态栏、tabBar、navigationBar的高度,只有320*367高度。

解决方法:如该View非tableView或scrollView,建议在storyboard中设置该控制器的"under top bars"和"underbottom bars"属性,将IOS7中的View变为320*367

 

 

[JNSettingItemsetDestVcClass:]: unrecognized selector sent to instance 0x786ca120

原因:子类JNSettingArrowItem继承父类JNSettingItem,增加一项属性,并重写父类方法,对增加的属性进行赋值时报错。

在重写父类时调用了父类的方法来创建一个对象。而父类是通过[[JNSettingItemalloc] init]来创建对象的,从而导致不管是谁调用,创建的都是JNSettingItem对象。当子类调用父类的方法来创建对象时,创建的依旧是JNSettingItem而非JNSettingArrowItem。父类对象没有新增加的那条属性,所以报错!!

解决方法:父类在创建对象时应使用[[selfalloc] init]来创建对象,谁调用创建谁,子类调用即创建子类

 

 

self.imageView.image = [UIImageimageNamed:@"move@2x.png"];

运行结果并没有显示图片,而self.imageView.image = [UIImageimageNamed:@"move"];能显示图片,因此确定因为后缀@2x.png使得图片无法解析(图片的实际名称是move@2x.png)。但在另一份由Xcode5.1创建的代码,用Xcode6.1运行,却能使用move@2x.png解析图片。因此得出的结论是编译器问题

解决方法:在解析数据模型时,重写图片名属性的setter方法(例如用icon来存放图片名,则重写setIcon方法),对图片名进行字符串处理,[iconstringByReplacingOccurrencesOfString:@"@2x.png"withString:@""];将图片名中的@2x.png替换为空即可。

 

0 0
原创粉丝点击