1 Preface
Through this study, we can understand the differences between the Objective-C method and getting variables in Block Objects.
2. code example
Main. m
[Plain]
# Import <Foundation/Foundation. h>
# Import "TestDemo. h"
Int main (int argc, const char * argv [])
{
@ Autoreleasepool {
TestDemo * test = [[TestDemo alloc] init];
// [Test log1];
// [Test simpleMethod];
// [Test simpleMethod2];
// [Test simpleMethod3];
// [Test callCorrectBlockObject];
// [Test simpleMethod4];
// [Test log2];
// [Test scopeTest];
[Test scopeTest2];
}
Return 0;
}
# Import <Foundation/Foundation. h>
# Import "TestDemo. h"
Int main (int argc, const char * argv [])
{
@ Autoreleasepool {
TestDemo * test = [[TestDemo alloc] init];
// [Test log1];
// [Test simpleMethod];
// [Test simpleMethod2];
// [Test simpleMethod3];
// [Test callCorrectBlockObject];
// [Test simpleMethod4];
// [Test log2];
// [Test scopeTest];
[Test scopeTest2];
}
Return 0;
}
TestDemo. h
[Plain] view plaincopyprint? # Import <Foundation/Foundation. h>
@ Interface TestDemo: NSObject
@ Property (nonatomic, strong) NSString * stringProperty;
-(Void) log1;
-(Void) simpleMethod;
-(Void) simpleMethod2;
-(Void) simpleMethod3;
-(Void) callCorrectBlockObject;
-(Void) simpleMethod4;
-(Void) log2;
-(Void) scopeTest;
-(Void) scopeTest2;
@ End
# Import <Foundation/Foundation. h>
@ Interface TestDemo: NSObject
@ Property (nonatomic, strong) NSString * stringProperty;
-(Void) log1;
-(Void) simpleMethod;
-(Void) simpleMethod2;
-(Void) simpleMethod3;
-(Void) callCorrectBlockObject;
-(Void) simpleMethod4;
-(Void) log2;
-(Void) scopeTest;
-(Void) scopeTest2;
@ End
TestDemo. m
[Plain]
# Import "TestDemo. h"
@ Implementation TestDemo
@ Synthesize stringProperty;
Void (^ independentBlockObject) (void) = ^ (void ){
NSInteger localInteger = 10;
NSLog (@ "local integer = % ld", (long) localInteger );
LocalInteger = 20;
NSLog (@ "local integer = % ld", (long) localInteger );
};
-(Void) log1 {
IndependentBlockObject ();
}
// Read-only
-(Void) simpleMethod {
NSUInteger outsideVariable = 10;
NSMutableArray * array = [NSMutableArray alloc]
InitWithObjects: @ "obj1 ",
@ "Obj2", nil];
[Array sortUsingComparator: ^ NSComparisonResult (id obj1, id obj2 ){
NSUInteger insideVariable = 20;
NSLog (@ "Outside variable = % lu", (unsigned long) outsideVariable );
NSLog (@ "Inside variable = % lu", (unsigned long) insideVariable );
/* Return value for our block object */
Return NSOrderedSame;
}];
}
// You can specify
-(Void) simpleMethod2 {
_ Block NSUInteger outsideVariable = 10;
NSMutableArray * array = [NSMutableArray alloc]
InitWithObjects: @ "obj1 ",
@ "Obj2", nil];
[Array sortUsingComparator: ^ NSComparisonResult (id obj1, id obj2 ){
NSUInteger insideVariable = 20;
OutsideVariable = 30;
NSLog (@ "Outside variable = % lu", (unsigned long) outsideVariable );
NSLog (@ "Inside variable = % lu", (unsigned long) insideVariable );
/* Return value for our block object */
Return NSOrderedSame;
}];
}
// Obtain self
-(Void) simpleMethod3 {
NSMutableArray * array = [NSMutableArray alloc]
InitWithObjects: @ "obj1 ",
@ "Obj2", nil];
[Array sortUsingComparator: ^ NSComparisonResult (id obj1, id obj2 ){
NSLog (@ "self = % @", self );
/* Return value for our block object */return NSOrderedSame;
}];}
// No-change Block Object requires passing parameters to obtain self
Void (^ correctBlockObject) (id) = ^ (id self ){
NSLog (@ "self = % @", self );
};
-(Void) callCorrectBlockObject {
CorrectBlockObject (self );}
// Modify class attributes
-(Void) simpleMethod4 {
NSMutableArray * array = [NSMutableArray alloc]
InitWithObjects: @ "obj1 ",
@ "Obj2", nil];
[Array sortUsingComparator: ^ NSComparisonResult (id obj1, id obj2 ){
NSLog (@ "self = % @", self );
Self. stringProperty = @ "Block Objects ";
NSLog (@ "String property = % @", self. stringProperty );
/* Return value for our block object */
Return NSOrderedSame;
}];
}
// Within an independent Block Object, you cannot use dot notation to read and write a declared attribute. In this scenario, you can use the getter and setter methods of this merging attribute to replace dot notation:
Void (^ correctBlockObject1) (id) = ^ (id self) {NSLog (@ "self = % @", self );
/* This will work fine */
[Self setStringProperty: @ "Block Objects"];/* This will work fine as well */
NSLog (@ "self. stringProperty = % @", [self stringProperty]);
};
-(Void) log2 {
CorrectBlockObject1 (self );
}
// When it appears in inline Block Objects, there is a very important rule that you must remember: inline Block Objects will copy values for these variables in its lexical area. What happens here is that the Block Object itself has a read-only copy of the integerValue variable at the place where the Block is executed.
Typedef void (^ BlockWithNoParams) (void );
-(Void) scopeTest {
NSUInteger integerValue = 10;
/************* Definition of internal block object ***************/
BlockWithNoParams myBlock = ^ {
NSLog (@ "Integer value inside the block = % lu", (unsigned long) integerValue );
};
/************* End definition of internal block object *****************/integerValue = 20;
/* Call the block here after changing
Value of the integerValue variable */
MyBlock ();
NSLog (@ "Integer value outside the block = % lu", (unsigned long) integerValue );
}
// Variable value change test
-(Void) scopeTest2 {
_ Block NSUInteger integerValue = 10;
/************* Definition of internal block object ***************/
BlockWithNoParams myBlock = ^ {
NSLog (@ "Integer value inside the block = % lu", (unsigned long) integerValue );
};
/************* End definition of internal block object *****************/integerValue = 20;
/* Call the block here after changing
Value of the integerValue variable */
MyBlock ();
NSLog (@ "Integer value outside the block = % lu ",
(Unsigned long) integerValue );
}
@ End
# Import "TestDemo. h"
@ Implementation TestDemo
@ Synthesize stringProperty;
Void (^ independentBlockObject) (void) = ^ (void ){
NSInteger localInteger = 10;
NSLog (@ "local integer = % ld", (long) localInteger );
LocalInteger = 20;
NSLog (@ "local integer = % ld", (long) localInteger );
};
-(Void) log1 {
IndependentBlockObject ();
}
// Read-only
-(Void) simpleMethod {
NSUInteger outsideVariable = 10;
NSMutableArray * array = [NSMutableArray alloc]
InitWithObjects: @ "obj1 ",
@ "Obj2", nil];
[Array sortUsingComparator: ^ NSComparisonResult (id obj1, id obj2 ){
NSUInteger insideVariable = 20;
NSLog (@ "Outside variable = % lu", (unsigned long) outsideVariable );
NSLog (@ "Inside variable = % lu", (unsigned long) insideVariable );
/* Return value for our block object */
Return NSOrderedSame;
}];
}
// You can specify
-(Void) simpleMethod2 {
_ Block NSUInteger outsideVariable = 10;
NSMutableArray * array = [NSMutableArray alloc]
InitWithObjects: @ "obj1 ",
@ "Obj2", nil];
[Array sortUsingComparator: ^ NSComparisonResult (id obj1, id obj2 ){
NSUInteger insideVariable = 20;
OutsideVariable = 30;
NSLog (@ "Outside variable = % lu", (unsigned long) outsideVariable );
NSLog (@ "Inside variable = % lu", (unsigned long) insideVariable );
/* Return value for our block object */
Return NSOrderedSame;
}];
}
// Obtain self
-(Void) simpleMethod3 {
NSMutableArray * array = [NSMutableArray alloc]
InitWithObjects: @ "obj1 ",
@ "Obj2", nil];
[Array sortUsingComparator: ^ NSComparisonResult (id obj1, id obj2 ){
NSLog (@ "self = % @", self );
/* Return value for our block object */return NSOrderedSame;
}];}
// No-change Block Object requires passing parameters to obtain self
Void (^ correctBlockObject) (id) = ^ (id self ){
NSLog (@ "self = % @", self );
};
-(Void) callCorrectBlockObject {
CorrectBlockObject (self );}
// Modify class attributes
-(Void) simpleMethod4 {
NSMutableArray * array = [NSMutableArray alloc]
InitWithObjects: @ "obj1 ",
@ "Obj2", nil];
[Array sortUsingComparator: ^ NSComparisonResult (id obj1, id obj2 ){
NSLog (@ "self = % @", self );
Self. stringProperty = @ "Block Objects ";
NSLog (@ "String property = % @", self. stringProperty );
/* Return value for our block object */
Return NSOrderedSame;
}];
}
// Within an independent Block Object, you cannot use dot notation to read and write a declared attribute. In this scenario, you can use the getter and setter methods of this merging attribute to replace dot notation:
Void (^ correctBlockObject1) (id) = ^ (id self) {NSLog (@ "self = % @", self );
/* This will work fine */
[Self setStringProperty: @ "Block Objects"];/* This will work fine as well */
NSLog (@ "self. stringProperty = % @", [self stringProperty]);
};
-(Void) log2 {
CorrectBlockObject1 (self );
}
// When it appears in inline Block Objects, there is a very important rule that you must remember: inline Block Objects will copy values for these variables in its lexical area. What happens here is that the Block Object itself has a read-only copy of the integerValue variable at the place where the Block is executed.
Typedef void (^ BlockWithNoParams) (void );
-(Void) scopeTest {
NSUInteger integerValue = 10;
/************* Definition of internal block object ***************/
BlockWithNoParams myBlock = ^ {
NSLog (@ "Integer value inside the block = % lu", (unsigned long) integerValue );
};
/************* End definition of internal block object *****************/integerValue = 20;
/* Call the block here after changing
Value of the integerValue variable */
MyBlock ();
NSLog (@ "Integer value outside the block = % lu", (unsigned long) integerValue );
}
// Variable value change test
-(Void) scopeTest2 {
_ Block NSUInteger integerValue = 10;
/************* Definition of internal block object ***************/
BlockWithNoParams myBlock = ^ {
NSLog (@ "Integer value inside the block = % lu", (unsigned long) integerValue );
};
/************* End definition of internal block object *****************/integerValue = 20;
/* Call the block here after changing
Value of the integerValue variable */
MyBlock ();
NSLog (@ "Integer value outside the block = % lu ",
(Unsigned long) integerValue );
}
@ End
Running result
22:25:34. 087 BlockObjectParamTest [946: 303] Integer value inside the block = 20
22:25:34. 089 BlockObjectParamTest [946: 303] Integer value outside the block = 20