IOS开发基础知识--碎片45

1:iOS SEL的简单总结

SEL就是对方法的一种包装。包装的SEL类型数据它对应相应的方法地址,找到方法地址就可以调用方法

a.方法的存储位置

在内存中每个类的方法都存储在类对象中

每个方法都有一个与之对应的SEL类型的数据

根据一个SEL数据就可以找到对应的方法地址,进而调用方法

SEL类型的定义:  typedef struct objc_selector *SEL

b.SEL对象的创建

SEL s1 = @selector(test1);   // 将test1方法包装成SEL对象 

SEL s2 = NSSelectorFromString(@"test1");   // 将一个字符串方法转换成为SEL对象

c.SEL对象的其他用法

// 将SEL对象转换为NSString对象  

NSString *str = NSStringFromSelector(@selector(test));

实例:

Person *p = [Person new];

// 调用对象p的test方法

[p performSelector:@selector(test)];

[person performSelector:@selector(test2:) withObject:@"传入参数"];
Person类代码:

#import "Person.h"
@implementation Person
- (void)test
{
    NSLog(@"无参数的对象方法");
}
- (void)test2:(NSString *)str
{
    NSLog(@"带有参数的方法%@",str);
}
@end

d:在数组中的运用

// 对一个数组array的每个元素执行一次test方法

[array makeObjectsPerformSelector:@selector(test)];

[array makeObjectsPerformSelector:@selector(test)  withObject:@"aaa"];
//对一个数组array进行排序

[array sortedArrayUsingSelector:@selector(compare:)];

e:关于Sel传参运用(target - action设计模式)

在Button中我们经常用下面进行事件增加代码:

- (void)addTarget:(nullable id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;

实例:

#import <UIKit/UIKit.h>

@interface TapView : UIView
//目标
@property(weak,nonatomic)id target;
//行为
@property(assign,nonatomic)SEL action;

//自定义方法
-(void)addCustomtarget:(id)target andAction:(SEL)action;

@end
#import "TapView.h"

@implementation TapView

//自定义方法
-(void)addCustomtarget:(id)target andAction:(SEL)action{
    _action = action;
    _target = target;
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //当视图点击的时候,target去执行action的方法并把自己传过去.
    //首先代理不能是空,而且代理(代理是对象!)的类中有方法并且能传出过来.
    if (nil != _target && [[_target class] instancesRespondToSelector:_action]) {
        [_target performSelector:_action withObject:self];
    }
}

另一个实例:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import "Debug.h" // not given; just an assert

@interface NSObject (Extras)

// Enforce the rule that the selector used must return void.
- (void) performVoidReturnSelector:(SEL)aSelector withObject:(id)object;
- (void) performVoidReturnSelector:(SEL)aSelector;

@end

@implementation NSObject (Extras)

// Apparently the reason the regular performSelect gives a compile time warning is that the system doesn‘t know the return type. I‘m going to (a) make sure that the return type is void, and (b) disable this warning
// See http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown

- (void) checkSelector:(SEL)aSelector {
    // See http://stackoverflow.com/questions/14602854/objective-c-is-there-a-way-to-check-a-selector-return-value
    Method m = class_getInstanceMethod([self class], aSelector);
    char type[128];
    method_getReturnType(m, type, sizeof(type));

    NSString *message = [[NSString alloc] initWithFormat:@"NSObject+Extras.performVoidReturnSelector: %@.%@ selector (type: %s)", [self class], NSStringFromSelector(aSelector), type];
    NSLog(@"%@", message);

    if (type[0] != ‘v‘) {
        message = [[NSString alloc] initWithFormat:@"%@ was not void", message];
        [Debug assertTrue:FALSE withMessage:message];
    }
}

- (void) performVoidReturnSelector:(SEL)aSelector withObject:(id)object {
    [self checkSelector:aSelector];

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    // Since the selector (aSelector) is returning void, it doesn‘t make sense to try to obtain the return result of performSelector. In fact, if we do, it crashes the app.
    [self performSelector: aSelector withObject: object];
#pragma clang diagnostic pop
}

- (void) performVoidReturnSelector:(SEL)aSelector {
    [self checkSelector:aSelector];

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [self performSelector: aSelector];
#pragma clang diagnostic pop
}

@end

2:代理模式实例

#import <UIKit/UIKit.h>

@protocol TouchViewDelegate <NSObject>
-(void)changeViewColor:(UIColor *)color;
@end

@interface TouchView : UIView
//声明一个代理,这个代理遵守TouchViewDelegate协议,
@property(nonatomic,assign)id<TouchViewDelegate> delegate;
@end
#import "TouchView.h"

@implementation TouchView

//我们还是用touchesBegandian
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    if (nil != self.delegate && [self.delegate respondsToSelector:@selector(changeViewColor:)]) {
        //我们传一个颜色到我们的ViewController去.
        [self.delegate changeViewColor:[UIColor brownColor]];
    }
}

@end
运用代码:

#import "ViewController.h"
#import "TouchView.h"

//在这里ViewController 要遵守协议....
@interface ViewController ()<TouchViewDelegate>

@property(nonatomic,strong)TouchView *touchView;

@end

@implementation ViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    self.touchView = [[TouchView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];

    self.touchView.backgroundColor = [UIColor redColor];
    //指定touchView的代理为ViewController.即为本身~
    self.touchView.delegate =self;

    [self.view addSubview: self.touchView];
}

-(void)changeViewColor:(UIColor *)color{
    //现在参数color是有值的,这是因为在TouchView那个页面传过来的.
    self.touchView.backgroundColor = color;
}
@end

3:关于Bolck运用

#import <UIKit/UIKit.h>

//给block改名成MyBlock
typedef void(^MyBlock)(NSString *);

@interface OtherViewController : UIViewController

//ARC:语义设置使用strong即可
@property(nonatomic,strong)MyBlock block;

@end
#import "OtherViewController.h"

@interface OtherViewController ()
@property(nonatomic,strong)UITextField *textField;
@end

@implementation OtherViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 100, 414, 40)];
    self.textField.backgroundColor = [UIColor lightGrayColor];
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview: self.textField];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    self.block(_textField.text);
    [self.navigationController popViewControllerAnimated:YES];
}
@end
运用代码:

    OtherViewController *otherVC = [[OtherViewController alloc]init];
    __weak typeof(self)weak = self;
    //给block赋值~
    otherVC.block = ^(NSString *string){
        weak.label.text = string;
    };

    [self.navigationController pushViewController:otherVC animated:YES];

4:UIButton的几种触发方式

a、UIControlEventTouchDown

  指鼠标左键按下(注:只是“按下”)的动作

b、UIControlEventTouchDownRepeat

  指鼠标左键连续多次重复按下(注:只是“按下”)的动作,比如,鼠标连续双击、三击、……、多次连击。

  说明:多次重复按下时,事件序列是这样的:

  UIControlEventTouchDown ->

  (UIControlEventTouchUpInside) ->

  UIControlEventTouchDown -> 

  UIControlEventTouchDownRepeat -> 

  (UIControlEventTouchUpInside) -> 

  UIControlEventTouchDown -> 

  UIControlEventTouchDownRepeat -> 

  (UIControlEventTouchUpInside) ->

  ......

  除了第一次按下外,后面每次摁下都是一个UIControlEventTouchDown事件,然后紧跟一个UIControlEventTouchDownRepeat事件。

cUIControlEventTouchDragInside

  指按下鼠标,然后在控件边界范围内拖动。

dUIControlEventTouchDragOutside

  与UIControlEventTouchDragInside不同的是,拖动时,鼠标位于控件边界范围之外。

  但首先得有个UIControlEventTouchDown事件,然后接一个UIControlEventTouchDragInside事件,再接一个UIControlEventTouchDragExit事件,这时,鼠标已经位于控件外了,继续拖动就是UIControlEventTouchDragOutside事件了。

  具体操作是:在控件里面按下鼠标,然后拖动到控件之外。

eUIControlEventTouchDragEnter

  指拖动动作中,从控件边界外到内时产生的事件。

fUIControlEventTouchDragExit

  指拖动动作中,从控件边界内到外时产生的事件。

gUIControlEventTouchUpInside

  指鼠标在控件范围内抬起,前提先得按下,即UIControlEventTouchDownUIControlEventTouchDownRepeat事件。

hUIControlEventTouchUpOutside

  指鼠标在控件边界范围外抬起,前提先得按下,然后拖动到控件外,即 

  UIControlEventTouchDown -> 

  UIControlEventTouchDragInside(n ) -> 

  UIControlEventTouchDragExit -> 

  UIControlEventTouchDragOutside(n 

  时间序列,再然后就是抬起鼠标,产生UIControlEventTouchUpOutside事件。

5:让编译器对一些警告闭嘴

a:方法弃用告警

#pragma clang diagnostic push  

#pragma clang diagnostic ignored "-Wdeprecated-declarations"
//会报警告的方法,比如SEL
[TestFlight setDeviceIdentifier:[[UIDevice currentDevice] uniqueIdentifier]];  

#pragma clang diagnostic pop  

b:未使用变量

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"   

int a;   

#pragma clang diagnostic pop 
时间: 2024-12-06 04:35:21

IOS开发基础知识--碎片45的相关文章

iOS开发基础知识--碎片5

iOS开发基础知识--碎片5  二十三:addSubview和insertSubview 区别 addSubview 是将view加到所有层的最顶层 相当于将insertSubview的atIndex参数设置成view.subviews count 即 [view addSubview:oneview] == [view insertSubview:oneview atIndex:view.subviews count] addSubview是加到最后 insertSubview是加到指定的位置

iOS开发基础知识--碎片32

 iOS开发基础知识--碎片32 1:动画属性UIViewAnimationOptions说明 a:常规动画属性设置(可以同时选择多个进行设置) UIViewAnimationOptionLayoutSubviews:动画过程中保证子视图跟随运动. UIViewAnimationOptionAllowUserInteraction:动画过程中允许用户交互. UIViewAnimationOptionBeginFromCurrentState:所有视图从当前状态开始运行. UIViewAnimat

iOS开发基础知识--碎片1

iOS开发基础知识--碎片1  一:NSString与NSInteger的互换 NSInteger转化NSString类型:[NSString stringWithFormat: @"%d", NSInteger]; NSString转化 NSInteger类型:NSInteger = [NSString intValue]; *其它几个同理 [NSString boolValue].[NSString floatValue].[NSString doubleValue] 二:Obje

iOS开发基础知识--碎片3

iOS开发基础知识--碎片3  iOS开发基础知识--碎片3 十二:判断设备 //设备名称 return [UIDevice currentDevice].name; //设备型号,只可得到是何设备,无法得到是第几代设备 return [UIDevice currentDevice].model; //系统版本型号,如iPhone OS return [UIDevice currentDevice].systemVersion; //系统版本名称,如6.1.3 return [UIDevice

iOS开发基础知识--碎片2

iOS开发基础知识--碎片2 六:获得另一个控件器,并实现跳转 UIStoryboard* mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; UIViewController *registerViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"registerView

iOS开发基础知识--碎片23

iOS开发基础知识--碎片23  1:关于UITableView中关于行重复加载的问题 在Cell里重写prepareForReuse,对一些控件进行清空: 比较简单: -(void)prepareForReuse{ [super prepareForReuse]; _content_label.text = nil; _time_date_label.text = nil; _name_label.text = nil; _career_label.text = nil; } 下面这个是我在c

iOS开发基础知识--碎片21

iOS开发基础知识--碎片21  1:[UIScreen mainScreen].scale知识点 当屏幕分别为640x940时[[UIScreen mainScreen] scale]=2.0 当屏幕分别为320x480时[[UIScreen mainScreen] scale]=1.0 2:如何正确的绘制1像素的线 #define SINGLE_LINE_WIDTH (1 / [UIScreen mainScreen].scale) #define SINGLE_LINE_ADJUST_OF

iOS开发基础知识--碎片24

 iOS开发基础知识--碎片24 1:兼容字体大小6plue跟它以下的区别 #define FONT_COMPATIBLE_SCREEN_OFFSET(_fontSize_) [UIFont systemFontOfSize:(_fontSize_ *([UIScreen mainScreen].scale) / 2)] 在iPhone4~6中,缩放因子scale=2:在iPhone6+中,缩放因子scale=3 运用时: myLabel.font=FONT_COMPATIBLE_SCREEN_

iOS开发基础知识--碎片6

iOS开发基础知识--碎片6  三十三:IOS多视图跳转方法 第一种: 跳转:[self presentModalViewController:control animated:YES]; 返回:[self dismissModalViewControllerAnimated:YES]; 第二种: 跳转:[self.navigationController pushViewController:subTableViewController animated:YES]; 返回:[self.navi