swift selector报错 in swift,多个参数的时候怎么写

3791人阅读
Swift入门教程(29)
原创blog,转载请注明出处
最近在用swift写代码,虽然遇到一些问题,但是代码量确实减了不少。
swfit入门教程系列会随着我使用swfit中的积累,不断地去修正更新
之前的教程
在swift中,函数有关键字func声明
格式
func 函数名(参数1,参数2,...)-&返回值{
func firstFunction()-&Int{
var result = 4
return result
println(firstFunction())//调用参数为空,返回值为Int
在Swift中,函数可以有任意类型的参数,因为Swift定义函数本身是一种类型,所以函数本身也可以返回
函数,或者一个函数作为另一个函数的参数
一、常见的使用函数方式
1、无参数,返回值为空
没有返回值的时候-&可以省略
func hwcFunction(){
println(&Hello hwc&)
2、多个参数,返回值唯一
func hwcFunction(first:String,second:String)-&String{
return first+second
println(hwcFunction(&hello&,&hwc&))
3、多个参数,多个返回值
在Swift中,多个返回值常用元组来返回
func hwcSwapString(first:String,second:String)-&(String,String){
return (second,first)
var (second,first) = hwcSwapString(&first&,&second&)
二、外部参数
从上面的例子中,我们发现,使用的时候我们并没有看到参数的信息,就是我们并不知道第一个参数是什
么意思,第二个参数是什么意思。外部参数可以完美解决这个问题
我们来举个例子
func addPersonalInformation(Name:String,Sex:String)-&String{
return Name+&:&+Sex
addPersonalInformation(&WenchenHuang&,&Male&)
比如输入WenchenHuang Male则返回WenchenHuang:Male.
但是,由于没有提示信息,我并不知道第一个参数是代表名字,第二个参数代表性别,这时候可以用外部
func addPersonalInformation(name Name:String,sex Sex:String)-&String{
return Name+&:&+Sex
addPersonalInformation(name:&WenchenHuang&,sex:&Male&)
调用的时候一目了然,知道哪一个参数代表什么意思
但是这样写仍然比较麻烦,我们不得不为同一个参数提供内部和外部两个名字
Swift为我们提供了一种简写外部参数的方式
只需要在内部参数前加上前缀,内部参数在调用的时候会体现
func addPersonalInformation(#name:String,#sex:String)-&String{
return name+&:&+sex
addPersonalInformation(name:&WenchenHuang&,sex:&Male&)
三、默认参数与变量参数
默认参数就是对参数有个默认值,在函数调用的时候,可以给这个参数传值,也可以不传,不传的时候使
用默认值
举个简单的例子
func hwcPrint(toPrint:Int = 10){
println(toPrint)
调用的时候
hwcPrint()//输出10
hwcPrint(toPrint:11)//输出11这里,我们不难看出,在调用的时候swift自动为我们生成了一个外部参数的名称
这是swift的一个特点:默认参数生成一个外部参数名称
可以使用下划线作为默认参数的外币名称,这样swfit不会提供外部参数名称,但不建议这么做
在swift中,函数传入的参数本身是常量,在函数中不能改变,如果想要让该参数作为可修改的副本,则添
注意:一个函数最多只能有一个可变参数,且必须为最后一个,为了减少内容歧义
func hwcPrint(toPrint:Int){
toPrint = toPrint+1//Wrong
println(toPrint)
func hwcPrint(var toPrint:Int){
toPrint = toPrint+1//Right
println(toPrint)
四、可变参数
所谓可变参数,就是想很多脚本语言那样,参数个数不明确,而在函数体内部,参数保存在一个数组里
可变参数用...表示
func addMultiString(toPrint:String...)-&String{
var resultString:String = &&
for tempString in toPrint{
resultString+=tempString
return resultString
var result1 = addMultiString(&hello&,&world&)
var result2 = addMultiString(&Wen&,&chen&,&Huang&)
五、输入输出参数inout
这类参数传入原值得引用,函数内对传入参数的操作会改变原始值,传入引用的时候需要使用&
func addOne(inout input:Int){
var test1 = 10
addOne(&test1)//test1 = 11
func addOne(var input:Int){
var test2 = 10
addOne(test3)//test2 = 10
六、函数类型
前面提到过,在swift中函数本身就是一个类型,类似于C语言中的函数指针
BTW:函数类型的理解对后面闭包的理解很重要
例如:上面的函数func addOne(input:Int)
函数类型就是(Int)-&()
所以,我们可以像其他类型一样使用函数类型
var add:(Int,Int)-&Int 声明一个入口参数是Int,Int返回值是Int的函数类型变量add
同样,函数类型也可以作为参数传递给函数
func addThree(addTwo:(Int,Int)-&Int,thrid:Int)-&Int{
return addTwo+thrid
函数类型也可以作为返回值
这里采用Apple官方文档里的说明:
func stepForward(input: Int) -& Int {
return input + 1
} func stepBackward(input: Int) -& Int {
return input - 1
func chooseStepFunction(backwards: Bool) -& (Int) -& Int {
return backwards ? stepBackward : stepForward
let moveNearerToZero = chooseStepFunction(currentValue & 0)
七、函数嵌套
何为函数嵌套,就是在函数里定义函数,默认嵌套的函数对外不可见,但是可在函数内部调用。
对上面函数进行重写
func chooseStepFunction(backwards: Bool) -& (Int) -& Int {
func stepForward(input: Int) -& Int {
return input + 1
func stepBackward(input: Int) -& Int {
return input - 1
return backwards ? stepBackward : stepForward
八、Selector
在swift中,建议不在使用selector,因为其不是类型安全的。但是对于熟悉Objective-C的程序员同学来说,很多方法讲不能调用,对此,swift对objective-C的selector直接传入函数名
myButton.addTarget(self, action: &buttonTapped:&, forControlEvents: .TouchUpInside)
let timer = NSTimer(timeInterval: 1, target: self, selector: &test&, userInfo: nil, repeats: false)
func test{
//Do something
function buttonTapped(sendr:AnyObject){
//Do something
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:454660次
积分:8080
积分:8080
排名:第1751名
原创:262篇
评论:121条
文章:54篇
阅读:102582
阅读:2273
阅读:21196
文章:14篇
阅读:38753
文章:14篇
阅读:34293
文章:18篇
阅读:30655
(2)(4)(5)(6)(4)(5)(1)(2)(4)(8)(13)(11)(7)(6)(9)(10)(21)(15)(17)(10)(15)(15)(25)(27)(17)(3)10811人阅读
swift(12)
作者:fengsh998原文地址:http://blog.csdn.net/fengsh998/article/details/转载请注明出处如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号fengsh998来支持我,谢谢!在OC中使用好好的performSelector,但不知为什么在swift有意的被拿掉了。更有甚者连IMP, objc_msgSend也不能用了。虽然想不通为什么,但应该有他的道理。就不纠结了。大家可能在OC中使用得更多的就是延时处理,及后台处理,或线程异步等。现在没有performSelector,哪在swift还有什么可以代替呢,当然有了,如GCD,NSTimer其实都可以近似的代替。如:NSTimer&let tm = NSTimer(timeInterval: 3.0, target: self, selector: &selectorfunc:&, userInfo: nil, repeats: false)
tm.fire()但个人感觉使NSTimer有个传上下文时获取与performSelector不一样。从上下文中拿到的是NSTimer需要再取userInfo才可以。但不管怎么样,可以实现延时处理。另外,我还自己做了一个swift 的扩展类(OC的catagray) 同样伪装了一个performselector方法。为什么讲是伪装,因为过程中在调用最终的selector时,用了线程处理。而不是理想的msgSend的方式(swift没有开源,没法看到实现,又不提供IMP,查了好多资料都没有讲执行Selector 的,如有大神发现,请告诉我。。。)实现://
ExpandNSObject.swift
Created by apple on 14-6-29.
Copyright (c) 2014年 fengsh. All rights reserved.
import Foundation
extension NSObject
func performSelectorOnMainThread(selector aSelector: Selector,withObject object:AnyObject! ,waitUntilDone wait:Bool)
if self.respondsToSelector(aSelector)
var continuego = false
let group = dispatch_group_create()
let queue = dispatch_queue_create(&com.fsh.dispatch&, nil)
dispatch_group_async(group,queue,{
dispatch_async(queue ,{
//做了个假的
NSThread.detachNewThreadSelector(aSelector, toTarget:self, withObject: object)
continuego = true
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
let ret = NSRunLoop.currentRunLoop().runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture() as NSDate)
while (!continuego && ret)
func performSelector(selector aSelector: Selector, object anArgument: AnyObject! ,delay afterDelay:NSTimeInterval)
if self.respondsToSelector(aSelector)
let minseconds = afterDelay * Double(NSEC_PER_SEC)
let dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds))
dispatch_after(dtime,dispatch_get_current_queue() , {
//做了个假的
NSThread.detachNewThreadSelector(aSelector, toTarget:self, withObject: anArgument)
}测试使用:
self.performSelector(selector:&refreshTable:&, object:nil ,delay:3.0)
self.performSelectorOnMainThread(selector:&refreshTable:&, withObject:nil,waitUntilDone:true)警告,如果使用performSelector最终执行的selector是在子线程中,如果seleoctor中有更新UI操作,需要回到主线程。就这点没有伪装好,真失败。。。。大家在使用过种中请谨慎,别外,如果有发现BUG,请告诉我。。。。。谢谢。别附swift源码文件位置:http://download.csdn.net/detail/fengsh998/7569569
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1060647次
积分:9325
积分:9325
排名:第1358名
原创:48篇
转载:50篇
评论:185条
QQ:(满)/3031702
(1)(2)(1)(13)(1)(1)(2)(1)(2)(2)(5)(2)(22)(18)(9)(4)(9)(16)(34)(15)(9)(1)(2)(1)(1)主题 : @selector设置的函数有多个回调参数时,每个参数如何设置
级别: 骑士
可可豆: 706 CB
威望: 706 点
在线时间: 84(时)
发自: Web Page
来源于&&分类
@selector设置的函数有多个回调参数时,每个参数如何设置&&&
比如:定义回调:UIImageWriteToSavedPhotosAlbum(imageviewWithTag.image, self, @selector(image:didFinishSavingWithError:tag:), nil);然后我写了一个回调调用回调:- (void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error tag: (int) tag两个问题:1)、如何设置@selector回调函数的参数,比如说我希望第一个参数是返回我传入的image,但我不知道怎么指定2)、我想定义回调的时候tag赋值为1,然后在调用回调的时候检查传过来的tag是不是1,用以进行一些操作区分,该如何设置?
UID: 83747
发帖: 3859
可可豆: 19528 CB
威望: 19399 点
在线时间: 2382(时)
发自: Web Page
你可以把多个参数放到一个dictionary里,然后只传这一个字典。
级别: 骑士
可可豆: 706 CB
威望: 706 点
在线时间: 84(时)
发自: Web Page
谢谢风月,我了解dictionary的思路,但这里我比较奇怪的是,我使用了@selector(image:didFinishSavingWithError:tag:)作为回调方式,居然也能传递过去了,image还是有值的,这个值哪来的?系统怎么知道我要的是哪个image的?
级别: 骑士
可可豆: 515 CB
威望: 515 点
在线时间: 327(时)
发自: Web Page
这种回调是不是只有第一个参数有值,其他应该都是nil吧和delegate还是不同
级别: 精灵王
可可豆: 1070 CB
威望: 1171 点
在线时间: 1002(时)
发自: Web Page
你传过去的是你调用这个@selector的对象地址
关注本帖(如果有新回复会站内信通知您)
苹果公司现任CEO是谁?2字 正确答案:库克
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版最近工作不是很忙,我花了两个星期的时间学习了一些swift。虽然swift出来快两年了,但是我一直没有去学习。近来听好多朋友说,他们已经开始用swift开发了,我决定学习一下swift基础的东西,在这里列出我一些学习总结。我不善于写文章,我就大片的粘上代码好了,有OC基础的人,基本上一看就懂了。
swift几个诡异符号的意义
苹果总是能弄出一些与众不同的代码书写方式,比如oc中的字符串写法。果然swift也一样,我在写一些代码的时候总是弹出警告,点击修复,系统会帮我加上一个问好(?)或者叹号(!),我但是就有点蒙了,这是什么意思呢?我没有系统看过swift的东西,直接按照oc的基础自己琢磨着写,导致好多的坑。那么这两个符号到底什么意思呢?我开始在找资料,原来这里有大学问啊!我先告诉说答案吧,问号(?)表示可选值或显示拆包,叹号(!)表示隐式拆包。
一切的原因在于一个swift的一个新的类型:optional类型(可选值,可以有值,也可以没有值),这是oc没有的类型。在oc中声明一个变量,可以不用赋初始值,因为系统会给变量初值。在swift中,变量是没有默认值的,所以使用变量之前必须赋初始值。当在声明一个变量不想给初始值的时候,就可以声明一个optional类型,例如:
var delegate : XXXDelegate?
在调用这个变量的时候,在后面也要加上“?”,如
self.delegate?.btnsAction(btn)
这样的实质就是:当Optional没有值时,返回的nil其实就是Optional.None,即没有值。除了None以外,还有一个Some,当有值时就是被Some包装的真正的值,所以我们拆包的动作其实就是将Some里面的值取出来。当变量不可能为空的时候,就可以用隐式拆包,就是在变量后面跟”!“。比如声明的时候:
var delegate : XXXDelegate!
这样在调用的时候变量后面就什么都不用加了。声明的显示可选值,也可以用!的方式调用。补充一点,在oc中,nill表示的是指针,只有对象才可以用nill,而在swift中,nill表示没有值,Int,Bool等在没有值得时候也是nill。
相关链接:
懒加载的写法
在oc中可以,可以重写get方法来实现懒加载。在swift中用关键字layz来实现懒加载。示例代码:
lazy var myTableView : UITableView = {
var myTableView = UITableView.init(frame:CGRectMake(0, 64, self.view.bounds.width, self.view.bounds.height - 64 - 49), style: UITableViewStyle.Plain)
myTableView.backgroundColor = kBorderLineColor()
myTableView.tableFooterView = UIView.init()
myTableView.delegate = self
myTableView.dataSource = self
//2.注册Cell
myTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: ID)
return myTableView
}()//使用一个闭包来实例化该属性
属性的观察者(willSet/didSet)
willSet在新的值被设置之前调用
willSet观察器会将新的属性值作为常量参数传入,在willSet的实现代码中可以为这个参数指定一个名称,如果不指定则参数仍然可用,这时使用默认名称newValue表示。
didSet在新的值被设置之后立即调用
didSet观察器会将旧的属性值作为参数传入,可以为该参数命名或者使用默认参数名oldValue。
我们可以didSet方法里进行一些赋值后的操作,相当于oc中的重写set方法
var model : UserProfile = UserProfile(){
nameL.text = model.name
headerImageV.sd_setImageWithURL(NSURL.init(string: model.avatar_hd), placeholderImage: UIImage.init(named: "timeline_image_placeholder"))
subL.text = model.userDescription
单例的写法
网上的swift单例有很多种写法,我还是在套用oc中的写法,换汤不换药
class var sharedInstance: LCInterfaceManager {
struct Static {
static var onceToken: dispatch_once_t = 0
static var instance: LCInterfaceManager? = nil
dispatch_once(&Static.onceToken) {
Static.instance = LCInterfaceManager()
return Static.instance!
相关链接:
协议的写法
这部分直接上代码了
protocol xxxViewDelegate{
func btnsAction(btn:UIButton) -& Void
var delegate : LCProfileHeaderViewDelegate?
@objc private
func buttonAction(btn:UIButton) -& Void {
self.delegate?.btnsAction(btn)
extension xxxViewController:xxxDelegate{
func btnsAction(btn: UIButton) {
if btn.tag == 101 {
let VC = LCFridensListVC.init()
self.navigationController!.pushViewController(VC, animated: true)
闭包反向传值
子这里我不去讲解swift闭包写法的原理,大家可以去网上学习,教程很多。我要举一个运用闭包实现方向传值的例子,相当于oc之中的block用法。
需求:AVc跳转到BVc中,在BVc中设置AVc的背景色为随机色。
AVc中的代码
import UIKit
let ID = "Cell"
ViewController: UIViewController{
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
override func touchesBegan(touches: Set&UITouch&, withEvent event: UIEvent?) {
weak var weakSelf = self
let VC = LCSTestVC.init()
VC.initBack { (changeToColor) in
weakSelf?.view.backgroundColor = changeToColor
self.presentViewController(VC, animated: true) {}
override func viewDidLoad(){
super.viewDidLoad()
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
BBC中的代码
import UIKit
class LCSTestVC: UIViewController {
typealias changeLastVcBacgroundColor = (color:UIColor)-&()
var myFunc = changeLastVcBacgroundColor?()
func initBack( mathFunction:(changeToColor:UIColor)-&() ){
myFunc = mathFunction
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.blueColor()
override func touchesBegan(touches: Set&UITouch&, withEvent event: UIEvent?) {
let r:CGFloat = CGFloat(CGFloat(random())/CGFloat(RAND_MAX))
let g:CGFloat = CGFloat(CGFloat(random())/CGFloat(RAND_MAX))
let b:CGFloat = CGFloat(CGFloat(random())/CGFloat(RAND_MAX))
myFunc!(color: UIColor.init(red: r , green: g, blue: b, alpha: 1.0))
self.dismissViewControllerAnimated(true) {
枚举的写法
enum buttonType : Int{
case back = 1
case search = 2
case more = 3
选择多个可选值的写法
let calendarUnit : NSCalendarUnit = [.Year , .Month , .Day ,.Hour, .Minute , .Second]
swift工具类的写法
swift中没有宏的概念,那么怎么实现类似于oc中pch文件中的定义全局宏的方法呢?答案是可以利用全局函数。
import Foundation
import UIKit
let kScreenWidth = UIScreen.mainScreen().bounds.size.width
let kScreenHeight = UIScreen.mainScreen().bounds.size.height
func DLog(input:AnyObject, function:String = #function, line:Int = #line){
print("- &func: \(function)& &line: \(line)&: \(input)")
let kBigTextFont = UIFont.systemFontOfSize(16)
let kMidTextFont = UIFont.systemFontOfSize(14)
let kSmallTextFont = UIFont.systemFontOfSize(12)
let kBorderLineThickness : CGFloat = 0.8
let kBorderCellLineThickness : CGFloat = 8
func RGBA (r:CGFloat, g:CGFloat, b:CGFloat, a:CGFloat) -& UIColor {
return UIColor (red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a)
重写系统答应print的内容
class AAA: NSObject {
override var description: String{
return "12345"
swift与OC混编的总结
现在的swift开发多数会用到混编。swift和oc是通过桥接文件来实现的。无论是在oc创建的项目中还中创建swift文件,还是在swift文件中创建oc文件,第一次都会自动提示建立桥接文件。名字为:xxx-Bridging-Header.h,并且自动添加文件路径。如果是导入另一只中语言的第三方库,就不会自动生成桥接文件,这时候就需要自己建立一个桥接文件。第一步:新建一个”.h”文件,也就是新建中的”Header.h“文件,名字可以模仿系统的写法”xxx(demo名字)-Bridging-Header.h“;第二步,桥接文件路径,在设置Build Settings 中搜索Bridging,结果中Objective-C Brindging Header 中拖入文件路径(前面的可以写成$(SRCROOT)/,这样就会自动生成项目文件路径,不会因为换了电脑就找不到文件路径),编译一下,就可以了。
在oc项目中引用swift文件,只需导入头文件
#import "项目名字-Swift.h"
这个文件是隐藏的,在工程中看不见。导入这个文件后就可以在oc使用swift写的类了。
在swift文件中引用oc的类,在桥接文件中引入需要引用oc的类的头文件,编译一下,就可以使用oc的类了。
多返回值函数的运用
swift的中的函数可以有多个返回值,具体的运用还没有比较好的列子。这里只是据下一多返回值函数的写法:
func createItem(frame:CGRect , topText:String , bottomText:String) -&(button:UIButton ,topLabel: UILabel , bottomLabel:UILabel){
let btn = UIButton.init(frame: frame)
let topL = UILabel.init()
topL.font = UIFont.boldSystemFontOfSize(16)
let bottomL = UILabel.init()
bottomL.font = kMidTextFont
bottomL.textColor = kMinBlackColor()
topL.text = topText
topL.sizeToFit()
topL.frame.size.width = frame.size.width
topL.textAlignment = NSTextAlignment.Center
bottomL.text = bottomText
bottomL.sizeToFit()
topL.frame.origin.x = btn.frame.size.width/2 - topL.frame.size.width/2
bottomL.frame.origin.x = btn.frame.size.width/2 - bottomL.frame.size.width/2
topL.frame.origin.y = btn.frame.size.height/2 - topL.frame.size.height/2 - 4
bottomL.frame.origin.y = btn.frame.size.height/2 + 4
btn.addSubview(topL)
btn.addSubview(bottomL)
return (btn , topL , bottomL)
let itemsLeft = self.createItem(CGRectMake(0, 0,frame.size.width/3, frame.size.height), topText: “0”, bottomText: “微博”)
itemsLeft.button.tag = 100
itemsLeft.button.addTarget(self, action: #selector(LCProfileHeaderView.buttonAction(_:)), forControlEvents: UIControlEvents.TouchUpInside)
self.statusCountLabel = itemsLeft.topLabel
self.addSubview(itemsLeft.button)
关于xib中自适应的总结
这部分跟swift没有什么关系,只是我以前一直在用代码的方式实现比如lable的大小的自适应。最近发现,其实xib中也可以做这些的。
需求:比如一个label后面跟着一个UIView,label的宽度随着字数的大小变换,这个功能是可以用xib实现的。
第一步,拖入控件,利用xib来控制好约束,这部分和平常xib的使用没有区别,不在讲述。
第二步,选中图中的label,操作如图:
第三步,保持选中label,操作
做完这些操作后,label的横向约束会变成虚线,大功告成。如果你的功能里有对最大宽度的控制,可以在layoutSubviews这个方法里用代码来控制。
目前我学习到的只有这些,以后有什么爬出的坑,再跟大家来分享吧。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:486次
排名:千里之外

我要回帖

更多关于 swift selector 的文章

 

随机推荐