一:swift,单例模式以及使用。
import Foundation
//创建一个单例类
class Singleton{
// 对于单例实例来说,需要创建一个唯一对外输出实例的方法
// 静态变量用static来处理
static let getSingleton = Singleton()
func doSomething() {
print(action)
}
}
使用:
let singleDemo = Singleton.getSingleton()
二:iOS静态库以及将第三方.Framework集成到自己的静态库里:参考该文章
三:通知要在不需要的时候及时释放,
要适当查看deinit()函数是否执行了。比如播放器在一个视频播放结束后会发送一个通知,如果在退出播放器时没有移除该通知,再次进入并播放一个视频结束后发送播放结束通知,通知函数会执行两遍(其中携带的一个信息就是上次没有移除的通知,比如说上次播放资源的URL。)
四:U盘安装Mac系统:
1,制作U盘启动盘,从App Store里面输入mojave搜索该工具后,点击下载。下载完成后会让安装,先不要点击继续。
2,在应用程序中找到磁盘工具,打开,抹掉U盘数据,并且重命名为Mojave,选择Mac OS扩展(日志式),抹去。
3,打开命令行,在里面输入:sudo /Applications/Install\ macOS\ Mojave.app/Contents/Resources/createinstallmedia --volume /Volumes/Mojave /Applications/Install\ macOS\ Mojave.app --nointeraction
4,上面执行完成后,启动盘就制作好了,将制作好的U盘插入要安装的Mac电脑,按下电源键并按住Option键不放。
5,出现相应画面后,点击install macOS Majave。
五:将图片进行resize:
var secondImage : UIImage?
let sizeChange = CGSize(width: 1280, height: 720)
UIGraphicsBeginImageContextWithOptions(sizeChange, false, 3.0)
secondImage?.draw(in: CGRect(origin: CGPoint.zero, size: sizeChange))
secondImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
六:将图片保存到相册:
UIImageWriteToSavedPhotosAlbum(result_image!, self, #selector(self.savedOK(image:didFinishSavingWithError:contextInfo:)), nil);直接调用该方法,并实现selector的方法:
@objc func savedOK(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: AnyObject){
if error != nil {
} else{
}
}
七:将pixelBuffer转成UIImage
import VideoToolbox
// 使用VideoToolbox 并对UIImage类进行扩展
extension UIImage{
public convenience init?(pixelBuffer: CVPixelBuffer) {
var cgImage: CGImage?
VTCreateCGImageFromCVPixelBuffer(pixelBuffer, nil, &cgImage)
if let cgImage = cgImage {
self.init(cgImage: cgImage)
} else {
return nil
}
}
}
八:将image转换成pixelBuffer
func imageToPixelBuffer(image:UIImage,width:Int,height:Int)->CVPixelBuffer?{
var maybePixelBuffer: CVPixelBuffer?
let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue,
kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue]
let status = CVPixelBufferCreate(kCFAllocatorDefault,
Int(width),
Int(height),
kCVPixelFormatType_32ARGB,
attrs as CFDictionary,
&maybePixelBuffer)
guard status == kCVReturnSuccess, let pixelBuffer = maybePixelBuffer else {
return nil
}
CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer)
guard let context = CGContext(data: pixelData,
width: Int(width),
height: Int(height),
bitsPerComponent: 8,
bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer),
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue)
else {
return nil
}
context.translateBy(x: 0, y: CGFloat(height))
context.scaleBy(x: 1, y: -1)
UIGraphicsPushContext(context)
image.draw(in: CGRect(x: 0, y: 0, width: width, height: height))
UIGraphicsPopContext()
CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
return pixelBuffer
}
九:image 转换成Array
extension UIImage {
/**
Converts the image into an array of RGBA bytes.
*/
@nonobjc public func toByteArray() -> [UInt8] {
let width = Int(size.width)
let height = Int(size.height)
var bytes = [UInt8](repeating: 0, count: width * height * 4)
bytes.withUnsafeMutableBytes { ptr in
if let context = CGContext(
data: ptr.baseAddress,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: width * 4,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) {
if let image = self.cgImage {
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
context.draw(image, in: rect)
}
}
}
return bytes
}
/**
Creates a new UIImage from an array of RGBA bytes.
*/
@nonobjc public class func fromByteArray(_ bytes: UnsafeMutableRawPointer,
width: Int,
height: Int) -> UIImage {
if let context = CGContext(data: bytes, width: width, height: height,
bitsPerComponent: 8, bytesPerRow: width * 4,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue),
let cgImage = context.makeImage() {
return UIImage(cgImage: cgImage, scale: 0, orientation: .up)
} else {
return UIImage()
}
}
}
十:查看沙盒文件(真机+模拟器)
1,模拟器比较简单,直接打印存放的文件地址,然后回到桌面 command+shift+G,直接输入该地址跳转即可。
2,真机:链接真机,在Xcode->window->Device and Smilulators, 在INSTALLED APPS栏中可以看到安装的APP,在最下面放的设置按钮:
点击show Container 可以查看沙盒内的文件,点击DownLoad Container可以把当前选中的app里沙盒的所有文件都下载下来,后缀为.xcappdata文件,然后选中->右键,显示包内容即可找到。
十一:读取yuv二进制NSData文件
let data = NSData.init(contentsOfFile: Bundle.main.path(forResource:
544x960_30.I420", ofType: nil)!)
let totalNum : Int = data!.length
var startNum : Int = 0
let datameta = Data.init(referencing: data!)
let width = Int(544)
let height = Int(960)
let y_num = width*height
var y_values = [UInt8](repeating: 0, count: y_num)
var toNum : Int = 0
let uv_num = width*height/2
var while_num : Int = 0
while startNum < totalNum {
print(while_num)
while_num = while_num + 1
toNum = startNum + y_num
let y_range : Range = startNum..<toNum
datameta.copyBytes(to: &y_values, from: y_range)
startNum = toNum
var uv_values = [UInt8](repeating: 0, count: uv_num)
toNum = startNum + uv_num
let uvrange : Range = startNum..<toNum
datameta.copyBytes(to: &uv_values, from: uvrange)
startNum = toNum
十二:清理Xcode缓存
command+shift+g 跳转路径到:~/Library/Developer/Xcode。
(1) Archives 存放的是Xcode打包时生成的文件,这里面的文件可以全部删掉。
(2) DerivedData 存放的是build生成的项目索引、build输出以及日志,这里的文件可以全部删除。
(3) iOS DeviceSupport 存放的是模拟器,对于你不需要的一些模拟器你可以删掉。即使不小心删掉了,也是可以重新下载的。
其他地方占用内存很少。
十三:swift类的实例当前的的引用计数
let count = CFGetRetainCount(self)
十四:CADisplayLink等时间控制类注意用完后释放
添加:invalidate()函数。否者监听对象不被释放。应当注意一切addtarget:self,等此类监时间在用完后的释放问题。
十五:多数内存泄漏起因
1.swift的闭包:引用了self,在in前面加上[unowned self]或者[weak self];2.Timer CADisplayLink 时间类使用注意释放。3,代理的使用,在声明代理属性的时候,使用weak。如 weak var delegate:Delegate。Delegate为协议‘’类。4,注意通知的释放,否者会导致通知执行的方法多吃执行问题:在下次进入的时候再次创建该通知,每次触发该通知时,会多次执行该方法。5,两类中互相包含导致的循环引用问题。
检测方法:https://juejin.im/post/5b0a1fd151882538bf5a6682
十六:Xcode 的instrument的官方使用说明
网址:https://help.apple.com/instruments/mac/current/
十七:他人总结的iOS开发经验,OC版本
网站:https://www.jianshu.com/p/1ff9e44ccc78
十八:APP转让和AppStore中公司信息的修改
只有账户持有人才有这个权限,即使是在app转让的接收方。
参考地址:https://help.apple.com/app-store-connect/?lang=zh-cn
转让和接受:https://help.apple.com/app-store-connect/?lang=zh-cn#/deve445a9a11
修改AppStore上公司的名称:https://www.jianshu.com/p/1d2262f69a6a
转让过程中需要Apple ID和团队ID,团队ID查找位置在:https://developer.apple.com/account/#/membership
十九:ipa文件上传到App Store的几种方法
xcode 11中去掉了application loader,那么上传App Store的几种替代方法如下。
一,给Xcode降级,然后就会有自带的Application Loader工具了。
二,下载Application Loader插件,装在Xcode目前的版本上。
三,直接通过通过Xcode上传ipa,有教程:https://help.apple.com/xcode/mac/current/#/dev442d7f2ca
四,通过altool上传ipa。altool教程:https://help.apple.com/asc/appsaltool/
五,通过Transporter应用上传ipa。Transporter是苹果新推出的应用,这是我最终选择的方式,也是我最推荐的方式,特别是我们这种通过其他工具编译出的ipa文件。在Mac上的App Store搜索“Transporter”,下载安装。