1 前言
通過本次學習,我們就能夠理解在 Objective-C 方法和在 Block Objects 中獲取變量的區別。
2 代碼實例
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();
}
//只讀
- (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;
}];
}
//可該
- (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;
}];
}
//獲得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;
}]; }
//無變化Block Object要獲得 self需要傳參數進去
void (^correctBlockObject)(id) = ^(id self){
NSLog(@"self = %@", self);
};
- (void) callCorrectBlockObject{
correctBlockObject(self); }
//修改類屬性
- (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;
}];
}
//在獨立 Block Object 內部,你不能使用 dot notation 讀寫一個已聲明屬性,在這個場景中可以使用這個合成屬性的 getter and setter 方法來代替 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);
}
//當出現在內聯 Block Objects 中,有一條非常重要的規則你必須記住:內聯 Block Objects 在其詞法區域 會為這些變量復制值。此處發生的事情是在執行 Block 的地方 Block Object 自身一直有一個 integerValue 變量的只讀復制。
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 the
value of the integerValue variable */
myBlock();
NSLog(@"Integer value outside the block = %lu",(unsigned long)integerValue);
}
//可改變變量值測試
-(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 the
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();
}
//只讀
- (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;
}];
}
//可該
- (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;
}];
}
//獲得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;
}]; }
//無變化Block Object要獲得 self需要傳參數進去
void (^correctBlockObject)(id) = ^(id self){
NSLog(@"self = %@", self);
};
- (void) callCorrectBlockObject{
correctBlockObject(self); }
//修改類屬性
- (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;
}];
}
//在獨立 Block Object 內部,你不能使用 dot notation 讀寫一個已聲明屬性,在這個場景中可以使用這個合成屬性的 getter and setter 方法來代替 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);
}
//當出現在內聯 Block Objects 中,有一條非常重要的規則你必須記住:內聯 Block Objects 在其詞法區域 會為這些變量復制值。此處發生的事情是在執行 Block 的地方 Block Object 自身一直有一個 integerValue 變量的只讀復制。
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 the
value of the integerValue variable */
myBlock();
NSLog(@"Integer value outside the block = %lu",(unsigned long)integerValue);
}
//可改變變量值測試
-(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 the
value of the integerValue variable */
myBlock();
NSLog(@"Integer value outside the block = %lu",
(unsigned long)integerValue);
}
@end
運行結果
2013-05-09 22:25:34.087 BlockObjectParamTest[946:303] Integer value inside the block = 20
2013-05-09 22:25:34.089 BlockObjectParamTest[946:303] Integer value outside the block = 20