Block和属性

发布时间:2020-07-01 12:16:23 作者:Im刘亚芳
来源:网络 阅读:762
#import <Foundation/Foundation.h>
typedef void(^MyBlock)();
typedef NSString *(^test)();
//int number=300;
//int (int x, int y)
//{
//    int sum;
//    sum = (x + y);
//    return sum;
//}
int main(int argc, const char * argv[])
{
    @autoreleasepool {
        
//        int a = 3, b = 4;
//        printf("%d\n",(a, b));
//       
        int (^p) (int, int);
        p = ^int (int x, int y)
        {
            int sum;
            sum = (x + y);
            return sum;
        };
        //类型:int (^)(int ,int)
        NSLog(@"sum == %d", p(3, 7));
        //block;本质上是匿名函数,于函数十分相似
        //返回值类型 (^变量名)(行参数) = ^返回值类型(行参){函数实现};
        //Block 的四种不同类型
        //1,无法返回值,无参数
        void (^firstBloack)() = ^void{
            NSLog(@"This is my FirstBlock");
        };
        //调用Bloack--声明作用。。
        firstBloack();
        //2.无返回值,有参数
        void (^secondBloack)(NSString *str) = ^void(NSString *str){
            NSLog(@"%@是2B", str);
        };
        secondBloack(@"泥煤");
        //3.有返回值,无参数
        NSString *(^thirdBloack)() = ^NSString *(){
            return @"希望世界和平";
        };
        NSLog(@"%@",thirdBloack());
//        thirdBloack();
        //4.有返回值,有参数,
        //返回值类型 (^变量名)(行参数) = ^返回值类型(行参){};
        NSString *(^fourthBlock)(NSString *str1, NSString *str2) = ^NSString *(NSString *str1, NSString *str2){
            
            return [str1 stringByAppendingString: str2];
        };
        NSLog(@"%@",fourthBlock(@"liu", @"yafang"));
        
        //联系,,IOS4中才有Block
        int (^getBlock)(NSString *str) = ^int (NSString *str){
            return [str intValue];
        };
        NSLog(@"%d",getBlock(@"9d1a2"));
        
        //Block和变量。。
        //在main函数里 在block外声明的局部变量在block内部调用时相当于有const修饰 不能修改变量的值.这时候我们通过__block来修饰变量改变这种模式.集体实现方式为:如果在block中访问全局变量就不需要__block修饰
        //当变量不加下划线下划线block即:__block (局部变量)在block内使用时当做常量来使用是readonly的,不能修改
       // __block的作用告诉编译器,编译时在block内部不要把外部变量当做常量来使用,还当做变量来使用
        
//        static int number = 300;  //还可以利用静态来休哥局部变量
        __block int number=300;  //__block修改变量,,,,全局和局部 ,,,
        MyBlock changeNumberBlock //代替下面注释的
       /* void(^changeNumberBlock)( ) */= ^void(){
            number = 400;
        };
        changeNumberBlock();
        NSLog(@"%d", number);
        //1.Block可以直接修改全局变量
        //2.Block可以访问局部变量,但不能直接修改局部变量的值,如果需要修改,在变量类型前面添加__block关键字
        
#pragma mark - typedef;
//        NSInteger
        MyBlock changeNumberBlock1 = ^void(){
            number = 100;
        };
        changeNumberBlock1();
        NSLog(@"%d", number);
        
        test append = ^NSString *(NSString *str1, NSString *str2){
            return [str1 stringByReplacingOccurrencesOfString:str1 withString:str2];
        };
        NSLog(@"%@",append(@"liu1", @"liuxiaomeng0"));
        
         test replace = ^NSString *(NSString *str1, NSString *str2){
             return [str1 stringByReplacingCharactersInRange:NSMakeRange(0, 2) withString:str2];
         };
        
        NSLog(@"%@", replace(@"liyafang", @"liu"));
        
        
        
        
    }
    return 0;
}

/////----下面转载于光远------////

block  注意实现形式

基本语法: 本质上是匿名函数,与函数真真十分相似 

称之为函数的实现部分,返回值省略不写  

变量block的类型 int (^)(int x, int y) 变量名字:block 可以为任意符合变量命名规范的名
=右边的block用来存储函数 初始值是一个函数的实现部分
        
int (^block)(int x ,int y) = ^(int x,int y){
            
return x + y;
        };
//相当于语句的定义,结尾加分号要注意

当把函数的实现赋给block之后,block变量就可以当做函数名来使用 

如:int sum = block(5,10);

        NSLog(@"sum = %d",sum);


 int (^block1)(int x,int y) = ^(int x,int y){

            return x > y ? x : y;
            };  初值的实现部分 

        
int max = block1(5,19);
        
NSLog(@"max = %d",max);
        
 
int (^block3)(int x,int y) = ^(int x,int y){
            
return x < y ? x : y;
        };
        
int min = block3(5,19);
        
NSLog(@"min = %d",min);


1.另外:也可以用对block进行typedef 

如:数据类型:void(^)() BLOCK新的变量类型名
        typedef void(^BLOCK)();

        BLOCK  sayHi = ^(){
            
NSLog(@"hello");
        };
        sayHi();//调用无参的函数 函数名+();

类比于函数指针.


2.还需注意:在main函数里 在block外声明的局部变量在block内部调用时相当于有const修饰 不能修改变量的值.这时候我们通过__block来修饰变量改变这种模式.集体实现方式为:如果在block中访问全局变量需要__block修饰

         当变量不加下划线下划线block:__block (局部变量)block内使用时当做常量来使用是readonly,不能修改
         
__block的作用告诉编译器,编译时在block内部不要把外部变量当做常量来使用,还当做变量来使用 
        
__block int a  = 10;
        
int (^max1)(int ,int )= ^(int x ,int y){
            a = 
20;
            
b = 30;
            
return
 x *a;
        };

(1)相同函数名的处理机制:对于定义在不同函数的相同名的两个变量.如果想要同时使用就把两者定义成为static变量 static int b = 120;,如果想要在一个函数里使用另一函数的全局变量,就使用extern进行导入.extern int b;


28.属性 用来替代settergetter,使用属性可以快速创建settergetter的声明,添加了设置实例变量操作的安全处理

setter 方法的作用 为单一的变量赋值

规范写法:-号方法 无返回值 有参数 名字以:set开头+实例变量名(首字母大写):(setter方法有且只有一个参数) + 参数类型(和实例变量类型相同) + 参数名(和实例变量名相同)
getter方法的作用 获取单一的实例变量值
规范写法: _号方法 有返回值(返回值类型和实例变量类型相同方法名和实例变量相同 无参数
属性,用来替代settergetter,使用属性可以快速创建settergetter的声明,添加了设置实例变量操作的安全处理
@property属性 NSString* 类型和实例变量类型相同 name 属性名和实例变量名相同
切记:@property只是自动生成settergetter的声明部分
类型相同是可以写一行
属性特性
1.读写特性 readonly readwrite
    1.readonly 
告诉编译器,属性在自动生成方法时只会生成getter 不会生成setter方法
    2.readwrite 
告诉编译器,属性在自动生成方法时,会生成为settergetter.系统默认的读写特性
    3.setter = aa: 
告诉编译器,当自动生成setter方法时,setter方法名为指定的名字aa:不采用默认
    4.getter = bb: 
告诉编译器,当自动生成getter方法时,getter方法名为指定的名字bb:不采用默认

2.原子性特性 nonatomic  atomic
   1.atomic:
原子特性 保证线程安全,内部做了安全处理(加锁和解锁)
   2.nonatomic:
非原子特性,不保证线程安全
 
因为对于settergetter方法的使用,比较频繁的在一段时间内要多次访问,降低程序的执行效率,使用nonatomic虽然不保证线程的安全,但使用一般情况下是安全的,所以对于原子特性使用nonatomic
3.
语义特性
   1.assign :
直接赋值 使用针对于基本数据类型,也可针对于对象类型.系统默认的语义特性.
   2.copy:
针对对象类型,而且要服从NSCopying协议的类型的对象才可以.恢复至出一个新的对象,拥有新的对象的所有权(引用计数+1)
   3.retain :
针对于对象类性(NSString,NSArray),会造成对象引用计数+1.


29.属性的实现  

声明部分:

@property(nonatomic,retainNSString *name; 

@property(nonatomicretainNSString *gender;

@property(nonatomicassignNSInteger age;

@property(nonatomicassignCGFloat height;绿色部分可省略 默认可省

@property(nonatomic,assignCGFloat weight;

实现部分:

@synthesize属性自动生成settergetter方法的实现部分 name 属性名,指定要实现哪一个属性生成settergetter方法 _name ,指定settergetter方法的内部实现要操作的实例变量
如果指定的实例变量没有定义,系统会自动生成,但是生成的实例变量是私有的,子类不能访问.
如果实例变量想让子类使用访问,那在.h文件必须定义实例变量
如果未指定settergetter内部所要访问的实例方法时,系统会自动生成和属性名一样的实例变量
如果对于settergetter方法我们一旦实现以后,系统就不会自动生成.
@synthesize name = _name,gender = _gender ,age = _age ,height = _height,weight = _weight;//附上要实现的实例变量
如果在.m文件中未通过@synthesize对属性进行合成,系统会自动合成,只不过系统默认的settergetter方法是: _属性名
如果将@synthesize省略,并且我们自己实现setter以及getter方法时,系统就不会自动生成对应的settergetter,还有实例变量.
1.当把语义特性声明为assign,settergetter的内部实现.同系统写的settergetter方法
- (void)setName:(NSString *)name{
    _name = name;
}
- (NSString *)name{
    return _name;
}

注意:二和三基本一样 不同部分为洋红色部分

2.当把语义特性声明为retain,settergetter的内部实现.
- (void)setName:(NSString *)name{
    if(_name != name){
        [_name release];
        _name = [name 
retain];
    }
}
- (NSString *)name{
    return [[_name retain] autorelease];
}

3.当把语义特性声明为copy,settergetter的内部实现.
- (void)setName:(NSString *)name{
    if(_name != name){
        [_name release];
        _name = [name 
copy];
    }
}
- (NSString *)name{
    return [[_name retain] autorelease];
}


推荐阅读:
  1. block怎么用
  2. block的传值和使用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

number return import

上一篇:INNODB的锁的类型

下一篇:化繁为简——算法之魅力

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》