swift中指针的使用
在 Swift 中,指针都使用一个特殊的类型来表示,那就是 UnsafePointer<T>。遵循了 Cocoa 的一贯不可变原则,UnsafePointer<T> 也是不可变的。当然对应地,它还有一个可变变体,UnsafeMutablePointer<T>。绝大部分时间里,C 中的指针都会被以这两种类型引入到 Swift 中:C 中 const 修饰的指针对应 UnsafePointer (最常见的应该就是 C 字符串的 const char * 了),而其他可变的指针则对应 UnsafeMutablePointer。除此之外,Swift 中存在表示一组连续数据指针的 UnsafeBufferPointer<T>,表示非完整结构的不透明指针 COpaquePointer 等等。另外你可能已经注意到了,能够确定指向内容的指针类型都是泛型的 struct,我们可以通过这个泛型来对指针指向的类型进行约束以提供一定安全性。
对 于一个 UnsafePointer<T> 类型,我们可以通过 memory 属性对其进行取值,如果这个指针是可变的 UnsafeMutablePointer<T> 类型,我们还可以通过 memory 对它进行赋值。比如我们想要写一个利用指针直接操作内存的计数器的话,可以这么做:
func incrementor(ptr: UnsafeMutablePointer<Int>) { ptr.memory += 1 } var a = 10 incrementor(&a)
a // 11
OC-JS简单封装
[webView stringByEvaluatingJavaScriptFromString:@"var script = document.createElement(‘script‘);" "script.type = ‘text/javascript‘;" "script.text = \"function myFunction() { " "var field = document.getElementsByName(‘q‘)[0];" "field.value=‘iCocos‘;" "document.forms[0].submit();" "}\";" "document.getElementsByTagName(‘head‘)[0].appendChild(script);"]; [webView stringByEvaluatingJavaScriptFromString:@"myFunction();"];
IBInspectable在IB的Attribute Inspector(属性检查器)中查看类的属性,而IBDesignable能实时更新视图,很厉害吧!
@IBDesignable class CustomView : UIView { @IBInspectable var borderColor: UIColor = UIColor.clearColor() @IBInspectable var borderWidth: CGFloat = 0 @IBInspectable var cornerRadius: CGFloat = 0 }
快速查找控制器
1 extension UIView { 2 3 4 func findController() -> UIViewController! { 5 return self.findControllerWithClass(UIViewController.self) 6 } 7 8 func findNavigator() -> UINavigationController! { 9 return self.findControllerWithClass(UINavigationController.self) 10 } 11 12 func findControllerWithClass<T>(clzz: AnyClass) -> T? { 13 var responder = self.nextResponder() 14 while(responder != nil) { 15 if (responder!.isKindOfClass(clzz)) { 16 return responder as? T 17 } 18 responder = responder?.nextResponder() 19 } 20 21 return nil 22 } 23 24 } 25 26 27 if UI_USER_INTERFACE_IDIOM() == .Pad { 28 // 设备是 iPad 29 } 30 31 if UIInterfaceOrientationIsPortrait(orientation) { 32 // 屏幕是竖屏 33 }
Xcode默认使用https的解决方案
<key>NSAppTransportSecurity</key><dict> <key>NSAllowsArbitraryLoads</key> <true/></dict>
IBInspectable在IB的Attribute Inspector(属性检查器)中查看类的属性,而IBDesignable能实时更新视图
IBDesignable
主要作用:可以显示出来你使用代码写的界面。
使用方法:在swift里,@IBDesignable关键字写在class前即可。
在OC里,是IB_DESIGNABLE这个关键字,写在@implementation前即可
IBInspectable
主要作用:使view内的变量可视化,并且可以修改后马上看到
使用方法:在swift里,@IBInspectable关键字写在需要显示的变量前即可
在OC里,是IBInspectable这个关键字,写在需要显示的变量前即可
另外附两个快捷键:
command+shift+O,快速打开需要的文件
control+shift+鼠标左击sb,可以选择需要的sb活着view
1 // 1.获取images文件夹中所有的文件 2 NSString *sourcePath = @"/Users/apple/Desktop/abc"; 3 NSString *dest = @"/Users/apple/Desktop/lnj"; 4 5 // 2.获取images文件夹中所有的文件 6 NSFileManager *mgr = [NSFileManager defaultManager]; 7 NSArray *subPaths = [mgr subpathsAtPath:sourcePath]; 8 // NSLog(@"%@", subPaths); 9 // 3.剪切文件到lnj文件夹中 10 11 for (int i = 0; i < subPaths.count; i++) { 12 // 3.1获取当前遍历到得文件的名称 13 NSString *fileNmae = subPaths[i]; 14 // 3.2根据当前文件的名称, 拼接全路径 15 NSString *fromPath = [sourcePath stringByAppendingPathComponent:fileNmae]; 16 NSString *toPath = [dest stringByAppendingPathComponent:fileNmae]; 17 NSLog(@"fromPath = %@", fromPath); 18 NSLog(@"toPath = %@", toPath); 19 20 [mgr moveItemAtPath:fromPath toPath:toPath error:nil]; 21 } 22 23 dispatch_apply(subPaths.count, dispatch_get_global_queue(0, 0), ^(size_t index) { 24 // 3.1获取当前遍历到得文件的名称 25 NSString *fileNmae = subPaths[index]; 26 // 3.2根据当前文件的名称, 拼接全路径 27 NSString *fromPath = [sourcePath stringByAppendingPathComponent:fileNmae]; 28 NSString *toPath = [dest stringByAppendingPathComponent:fileNmae]; 29 NSLog(@"fromPath = %@", fromPath); 30 NSLog(@"toPath = %@", toPath); 31 32 [mgr moveItemAtPath:fromPath toPath:toPath error:nil]; 33 34 }); 35
检查方法的可用性
用respondsToSelector检查框架内是否含有此方法。例如:iOS 9在Core Location框架中新增了allowsBackgroundLocationUpdates属性:
CLLocationManager *manager = [CLLocationManager new]; if ([manager respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) { // 在iOS 8中不可用 manager.allowsBackgroundLocationUpdates = YES; }
陷阱
这 些方法既难以维护,又没有看上去那么安全。也许某个API现在是公有的,但在早期的版本中却有可能是私有的。例如:iOS 9中新增了几个文本样式,如UIFontTextStyleCallout。如果只想在iOS 9中使用这种样式,你可以检查其是否存在,因为它在iOS 8中应该是null的:
if (UIFontTextStyleCallout) { textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleCallout]; }
不幸的是结果并非如此。原来这个标志在iOS 8中是存在的,只是没有宣布公有。使用一个私有的方法或值有可能出现难以预料的结果,况且这也和我们的想法不同。
Swift 2的方法
Swift 2内置了可用性检查,而且是在编译时进行检查。这意味着当我们使用当前部署版本不可用的API时,Xcode能够通知我们。例如:如果我在部署版本为iOS 8的情况下使用CNContactStore,Xcode将提出以下改进:
if #available(iOS 9.0, *) { let store = CNContactStore() } else { // 旧版本的情况 }
同样这可以取代我们之前使用的respondsToSelector:
let manager = CLLocationManager() if #available(iOS 9.0, *) { manager.allowsBackgroundLocationUpdates = true }
可用性检查的使用情形
#available条件适用于一系列平台(iOS, OSX, watchOS) 和版本号。例如:对于只在iOS 9或OS X 10.10上运行的代码:
if #available(iOS 9, OSX 10.10, *) { // 将在iOS 9或OS X 10.10上执行的代码 }
即使你的App并没有部署在其他平台,最后也需要用*通配符来包括它们。
如果某块代码只在特定的平台版本下执行,你可以用guard声明配合#available来提前return,这样可以增强可读性:
private func somethingNew() { guard #available(iOS 9, *) else { return } // 在iOS 9中执行的代码 let store = CNContactStore() let predicate = CNContact.predicateForContactsMatchingName("Zakroff") let keys = [CNContactGivenNameKey, CNContactFamilyNameKey] ... }
如果整个方法或类只在特定的平台版本下存在,用@available:
@available(iOS 9.0, *) private func checkContact() { let store = CNContactStore() // ... }
编译时的安全性检查
结束前,让我们再看看那个常量在iOS 9中公有却在iOS 8中私有的问题。如果部署版本为iOS 8,我们却把字体设置为一个只有iOS 9才能用的样式,这将产生一个编译错误:
label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleCallout)
- > ‘UIFontTextStyleCallout‘ is only available on iOS 9.0 or newer
Swift使其便于调试,同时能够根据平台版本赋一个合理的值:
if #available(iOS 9.0, *) { label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleCallout) } else { label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody) }