美文网首页
iOS知识点

iOS知识点

作者: 一吻江山 | 来源:发表于2017-05-18 16:02 被阅读127次

[TOC]

015


代码阅读target-action

(lldb) e id $view = (id) 0x7fbd71432590

(lldb) po [$view  allTargets]
{(
    <lldb.ViewController: 0x7feff2d67330>
)}

(lldb) po [$button actionsForTarget:(id)0x7feff2d67330 forControlEvent:0]

014


自动打包遇到的问题

当Team:Personal Team is not enrolled in the Apple Developer Program时,下面的命令导出ipa失败
失败原因${options_plist}所指定的文件中method字段写为了ad-hoc,修改为development就ok了

xcodebuild -exportArchive -archivePath ${archive_path} -exportPath ${ipa_path} -exportOptionsPlist ${options_plist}

上面命令的失败输出:
error: exportArchive: No signing certificate "iOS Distribution" found

Error Domain=IDECodesignResolverErrorDomain 
Code=1 "No signing certificate "iOS Distribution" found" 
UserInfo={
IDEProvisioningError_UserInfoKey_IDEProvisioningErrorPlatform=com.apple.platform.iphoneos, 
IDEProvisioningError_UserInfoKey_IDEProvisioningErrorAction=5, 
NSLocalizedRecoverySuggestion=No "iOS Distribution" signing certificate matching team ID "P9DNHPPVMB" with a private key was found.,
IDEProvisioningError_UserInfoKey_IDEProvisioningErrorSpecifier=iOS Distribution,
IDEProvisioningError_UserInfoKey_IDEProvisioningErrorTeam=<IDEProvisioningBasicTeam: 0x7f884413e0c0; teamID='P9DNHPPVMB', teamName='(null)'>,
NSLocalizedDescription=No signing certificate "iOS Distribution" found
}
Team:Personal Team is not enrolled in the Apple Developer Program.png

-exportOptionsPlist可以指向一个plist文件,文件内容大致如下:

plist文件.png
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>teamID</key>
    <string>P9DNHPPVMB</string>
    <key>method</key>
    <string>ad-hoc</string>
    <key>uploadSymbols</key>
    <true/>
    <key>provisioningProfiles</key>
    <dict>
        <key>com.jason.abcdefg</key>
        <string>6ce1bd8e-21b4-43c0-a00c-5aa86e131b45</string>
    </dict>
</dict>
</plist>

<key>provisioningProfiles</key> :
xxxx.mobileprovision[6ce1bd8e-21b4-43c0-a00c-5aa86e131b45.mobileprovision]
Xcode把Profiles下载到如下目录:
~/Library/MobileDevice/Provisioning Profiles

mobileprovision是二进制文件无法查看, 可以用如果下的命令查看文件内容

security cms -D -i 6ce1bd8e-21b4-43c0-a00c-5aa86e131b45.mobileprovision
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>AppIDName</key>
    <string>XC com jason abcdefg</string>
    <key>ApplicationIdentifierPrefix</key>
    <array>
    <string>P9DNHPPVMB</string>
    </array>
    <key>DeveloperCertificates</key>
    <array>
        <data>MIIFmjCCBIKgAwIBAgIISlCOHuhedtMwDQYJKoZIhvcNAQELBQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwNzIyMjM0NzMzWhcNMTkwNzIyMjM0NzMzWjCBjTEaMBgGCgmSJomT8ixkAQEMCk5OTDNENUg4MjIxOzA5BgNVBAMMMmlQaG9uZSBEZXZlbG9wZXI6IHpob3VqaWVfOTAzQDE2My5jb20gKFRDRExWRkVRSEopMRMwEQYDVQQLDApQOUROSFBQVk1CMRAwDgYDVQQKDAfmnbAg5ZGoMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPer0ggVn8D+jjuhHTxyFex3bk1Dp+Oxz7115mFwmwKwn0w7/RFFg87NpL3nGZA5FPpLdJfDPdZiVoNMcKA5Tl+KQRH9FYXENtli/Bn2/VEt9Cv8QQH71h26/U/mKtkBZCtxP4nR52v36naheUCS+2vB9UUy0Ndm2FnobegD8biJlJqtNFVYXTAQ+F/kJEnuLwWcr/uWmq4iteUvQxIOBkGlguw2g6Auw7/TjA1/6HGPaVsX3Tpz/M7A2I7nUB6QU54Z+sGnuMSJbelzwx8o1UyXTzgmuxaPMPUyARUETcDBKZLQ0QLNAkUCNpl1Ss6zv5trE06mbelquKBXp3BdUncCAwEAAaOCAfEwggHtMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUiCcXCam2GGCL7Ou69kdZxVJUo7cwPwYIKwYBBQUHAQEEMzAxMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5hcHBsZS5jb20vb2NzcDAzLXd3ZHIwMTCCAR0GA1UdIASCARQwggEQMIIBDAYJKoZIhvdjZAUBMIH+MIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMDYGCCsGAQUFBwIBFipodHRwOi8vd3d3LmFwcGxlLmNvbS9jZXJ0aWZpY2F0ZWF1dGhvcml0eS8wFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFHuh/bXHzpKtVf6EXpIIYrQ2j19hMA4GA1UdDwEB/wQEAwIHgDATBgoqhkiG92NkBgECAQH/BAIFADANBgkqhkiG9w0BAQsFAAOCAQEAo9AA9R9Lg6f77WY4n51KgP8MMHaEdDKmuji/sdHVhqCpMqfGdcVmweE2lp4M38g/SD2diOFL4YhXdlwG3e1jc68L8GIvfT+AeaAk3G2K7D6Ew6iR4vmAmWTUKbb8OIN7a5KGALKABfwAEDHynJnN+x2n7yCsQtlf1pF8vkYgmewDAeBPqc2ruq9WvxIcRDsAixEr0/f08zzohHSK0omAYSuKTd85UqRnZ1QUSbrDIG2U+H0qiS+0Qw4xyCHjlqtWRbMaoEppowcjgah8Llnp0Lel56mW0l4iMZdbHlRpsDbA+gX1tPeJN5ztvnNEjawDDQ8tT+U3RW7OcWrcIq43Cg==</data>
    </array>
    <key>Entitlements</key>
    <dict>
        <key>keychain-access-groups</key>
        <array>
            <string>P9DNHPPVMB.*</string>
        </array>
        <key>get-task-allow</key>
        <true/>
        <key>application-identifier</key>
        <string>P9DNHPPVMB.com.jason.abcdefg</string>
        <key>com.apple.developer.team-identifier</key>
        <string>P9DNHPPVMB</string>

    </dict>
    <key>ExpirationDate</key>
    <date>2018-11-01T11:22:49Z</date>
    <key>Name</key>
    <string>iOS Team Provisioning Profile: com.jason.abcdefg</string>
    <key>ProvisionedDevices</key>
    <array>
        <string>a82fecc1d3f1628f85e5055e238d8515f23624da</string>
    </array>
    <key>TeamIdentifier</key>
    <array>
        <string>P9DNHPPVMB</string>
    </array>
    <key>TeamName</key>
    <string>&#26480; &#21608;</string>
    <key>UUID</key>
    <string>6ce1bd8e-21b4-43c0-a00c-5aa86e131b45</string>
</dict>
</plist>

Xcode 10生成的ExportOptions.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>compileBitcode</key>
    <true/>
    <key>method</key>
    <string>development</string>
    <key>signingStyle</key>
    <string>automatic</string>
    <key>stripSwiftSymbols</key>
    <true/>
    <key>teamID</key>
    <string>P9DNHPPVMB</string>
    <key>thinning</key>
    <string>&lt;none&gt;</string>
</dict>
</plist>
ipa目录结构.png

013


iOS 中的数组排序操作

NSLiteralSearch
区分 同一个字符(如日文的片假字)的半角与全角状态[半角状态 > 全角状态]

NSWidthInsensitiveSearch
不区分 同一个字符(如日文的片假字)的半角与全角状态[半角状态 = 全角状态]
同时指定两个时,NSWidthInsensitiveSearch 比 NSLiteralSearch 的优先级高,综合起来的结果: [半角状态 = 全角状态]

NSForcedOrderingSearch
NSForcedOrderingSearch 的优先级最高

参考iOS 中的数组排序操作

012


工作线程中销毁对象

对象的销毁虽然消耗资源不多,但累积起来也是不容忽视的。通常当容器类持有大量对象时,其销毁时的资源消耗就非常明显。同样的,如果对象可以放到后台线程去释放,那就挪到后台线程去。这里有个小 Tip:把对象捕获到 block 中,然后扔到后台队列去随便发送个消息以避免编译器警告,就可以让对象在后台线程销毁了

NSArray *tmp = self.array;
self.array = nil;
dispatch_async(queue, ^{
    [tmp class];
});

引用自iOS 保持界面流畅的技巧

011


beginIgnoringInteractionEvents

UIApplication.shared.beginIgnoringInteractionEvents()
pvc.setViewControllers([vc], direction: dir, animated: true) { _ in 
  UIApplication.shared.endIgnoringInteractionEvents()         
}

In that code, I turn off user interaction when the page animation starts and turn it back on when the animation ends. The reason is that otherwise we can crash (or get into an incoherent state) if the user taps during the animation.

applicationWillTerminate:不一定被调用

For apps that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the app.
For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case. However, this method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason

像阅读类应用如:咪咕阅读、掌阅、QQ阅读有朗读功能,开启了Background Modes:


朗读功能开启Background Modes.png

开启后进入后台一段时间,app被杀掉,applicationWillTerminate就不一定被调用

010


UIScrollView的scrollRectToVisible: animated:方法应用

UIScrollView的scrollRectToVisible: animated:NO 可以使用UIScrollView立即停止滑动,而用设置contentOffset的方法,还会滑动一会儿。见图:


2种方法日志比较

代码如下:


日志代码

009


iphone5 iOS7上UIScrollView的contentSize不能设置为CGFLOAT_MAX

最近在做阅读的上下滑动翻页功能,自然想到了UIScrollView
为了能无限翻页,把UIScrollView.contentSize = CGSizeMake(width, CGFLOAT_MAX)
测试发现在iphone5 iOS7崩溃


崩溃截图

解决方法:
UIScrollView.contentSize = CGSizeMake(width, 2^31);
可能原因是iphone5 iOS7是32位,不能大于2^32

008


JSQMessages的问题在iOS11上崩溃的问题

JSQMessagesComposerTextView(@interface JSQMessagesComposerTextView : UITextView)有个属性:
@property (weak, nonatomic, nullable) id<JSQMessagesComposerTextViewPasteDelegate> pasteDelegate;

在iOS11上崩溃,原因:

@protocol UITextPasteConfigurationSupporting <UIPasteConfigurationSupporting>
@property (nonatomic, weak, nullable) id<UITextPasteDelegate> pasteDelegate;
@end

@interface UITextView () <UITextPasteConfigurationSupporting>
@end

UITextView实现了UITextPasteConfigurationSupporting协议,而UITextPasteConfigurationSupporting定义了pasteDelegate,JSQMessagesComposerTextView定义的pasteDelegate与系统的冲突了

解决方法:
修改JSQMessagesComposerTextView的pasteDelegate为jsq_pasteDelegate

007

NSKeyedUnarchiver在iOS8下读取plist的问题

v7.3.0前用:
[NSArray writeToFile:savedFileName atomically:YES]来保存搜索记录;是一个plist文件
v7.3.1后用:
[NSKeyedArchiver archiveRootObject:array toFile:savedFileName]来保存搜索记录;是一个二进制文件

savedFileName都是同一个文件,在v7.3.1上覆写了v7.3.0的plist文件为二进制文件

在iOS8.4下的系统用如下代码读取文件时,崩溃;但iOS10以上正常

    NSMutableArray *recordArray;
    recordArray = [NSKeyedUnarchiver unarchiveObjectWithFile:savedFileName];
    if (recordArray == nil) {
        //旧数据提取
        recordArray = [NSMutableArray arrayWithContentsOfFile:savedFileName];
    }

为了让全部iOS版本都正常,修改代码如下:

    NSMutableArray *recordArray;
    @try {
        recordArray = [NSKeyedUnarchiver unarchiveObjectWithFile:savedFileName];
        if (recordArray == nil) {
            //旧数据提取
            recordArray = [NSMutableArray arrayWithContentsOfFile:savedFileName];
        }
    }
    @catch (NSException* e) {
        recordArray = [NSMutableArray arrayWithContentsOfFile:savedFileName];
    }

006


状态栏样式引起的神样问题

问题描述:

  1. UINavigationController里的2个ViewController:XXPlayerViewController, XXDownloaderManagerViewController.
  2. XXPlayerViewController不显示NavigationBar,preferredStatusBarStyle方法返回UIStatusBarStyleLightContent
  3. XXDownloaderManagerViewController显示NavigationBar,没有重写preferredStatusBarStyle方法,默认返回UIStatusBarStyleDefault
ViewController NavigationBar preferredStatusBarStyle
XXPlayer Hide UIStatusBarStyleLightContent
XXDownloaderManager Show UIStatusBarStyleDefault

步骤:XXDownloaderManagerViewController侧滑显示XXPlayerViewController,侧滑取消,并马上点击NavigationBar的“返回”按键

问题:XXPlayerViewController显示了XXDownloaderManagerViewController的UINavigationItem

解决方法:自定义的UINavigationController实现如下方法

- (UIViewController *)childViewControllerForStatusBarStyle {
    return self.topViewController;
}

参考:Bug when swiping from view with uinavigationbar to one without

005


AVAudioSessionRouteChangeNotification一般不在主线程通知

AVAudioSessionRouteChangeNotification一般不在主线程通知,需要注意多线程问题

004


iOS7上的问题02

speedSlider已创建,并在视图层次中,创建时minimumTrackTintColor,maximumTrackTintColor不为代码中的颜色,这时候调整值(比如应用设置成夜间模式),在iOS7上不生效

    //UISlider *speedSlider
    self.speedSlider.minimumTrackTintColor = RGB_COLOR(200, 100, 100);
    self.speedSlider.maximumTrackTintColor = RGB_COLOR(195, 206, 217);

iOS7上的问题01

有这么个函数:

- (void)showMainViewController:(NSInteger)pageIndex
{
}

它有一个参数:(NSInteger)pageIndex,在iOS7上,如下调用会有问题:

//targetVC实现了showMainViewController:方法
[targetVC performSelector:@selector(showMainViewController:) withObject:@0];
//或
[targetVC performSelector:@selector(showMainViewController:) withObject:[NSNumber numberWithInteger:0]];    

问题:pageIndex的值不为0,更像一个内存地址
解决方法:

((void(*)(id, SEL, NSInteger))objc_msgSend)(targetVC, @selector(showMainViewController:), 0);

003


Locale改变 NSCurrentLocaleDidChangeNotification

  • 通用-日期与时间-24小时制,收到通知
  • 通用-日期与时间-时区,不会收到通知
  • 通用-语言与地区-日历,不会收到通知
  • 通用-语言与地区-地区,杀死应用程序
  • 通用-语言与地区-iPhone语言,杀死应用程序
  • 通用-语言与地区-温度单位,收到通知

002


让特定UICollectionViewCell滚到可见范围内

问题:调用UICollectionView scrollToItemAtIndexPath: atScrollPosition: animated:不能让Cell滚到可见范围内
方法:可以这么调用:

[UICollectionView performBatchUpdates:^{
    [UICollectionView scrollToItemAtIndexPath: atScrollPosition: animated:];
} completion:nil];

001


不要在applicationDidEnterBackground做长时间操作

1. 按Home键进入后台
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    sleep(10);//模拟长时间操作
}
2. 1秒后点击应用进入前台,应用能显示
3. 这时点击界面是没有响应的
4. 10秒后applicationWillEnterForeground,applicationDidBecomeActive才被调用

NSLiteralSearch
区分 同一个字符(如日文的片假字)的半角与全角状态[半角状态 > 全角状态]

NSWidthInsensitiveSearch
不区分 同一个字符(如日文的片假字)的半角与全角状态[半角状态 = 全角状态]
同时指定两个时,NSWidthInsensitiveSearch 比 NSLiteralSearch 的优先级高,综合起来的结果: [半角状态 = 全角状态]

NSForcedOrderingSearch
NSForcedOrderingSearch 的优先级最高

000


NSString enumerateSubstringsInRange: options: usingBlock:可以断句

应用场景:咪咕阅读,掌阅等朗读时分句子高亮

[string enumerateSubstringsInRange:NSMakeRange(0, string.length)
                           options:NSStringEnumerationBySentences | NSStringEnumerationLocalized
                        usingBlock:block];

比如:完整的内容为:


或格式化显示:


格式化内容

断句后的结果:


相关文章

网友评论

      本文标题:iOS知识点

      本文链接:https://www.haomeiwen.com/subject/crbsxxtx.html