第八课:
1、协议
另一种安全处理id类型的方式如:id <MyProtocol> obj
a.声明
@protocol Foo <Xyzzy, NSObject>//<>中的内容表示还需实现自哪些协议,所有协议的根协议一般都是NSObject
- (void)someMethod;//默认为必须实现的方法
@optional//可选方法声明
- (void)methodWithArgument:(BOOL)argument;
@required
@property (readonly) int readonlyProperty; //只有getter在协议中
@property NSString *readwriteProperty; //getter与setter都在协议中
- (int)methodThatReturnsSomething;
@end
b.在类中实现协议
@interface MyClass : NSObject <Foo>
//(do not have to declare Foo’s methods again here, it’s implicit that you implement it)
@end
//或者私有实现
@interface MyClass() <Foo>
@end
@implementation MyClass
//@required methods here!
@end
c.用途
①委托
②数据源
@property (nonatomic, weak) id <UISomeObjectDelegate> delegate;
@property (nonatomic, weak) id <UISomeObjectDataSource> dataSource;
③动画
2、Block(来源于API文档)
实际上为一段代码块,类似于C语言中的函数指针
a.声明
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
//int 为block返回值
//^表示为此为代码块
//myBlock为此代码块名
//int 为参数类型
//等号右边为block实现
block可以使用和他的同一范围内声明的变量,使用block与使用C函数类似
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
printf("%d", myBlock(3));
// prints "21"
b.直接使用block
block可以省略block声明直接使用
//直接使用block作为参数
qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) {
char *left = *(char **)l;
char *right = *(char **)r;
return strncmp(left, right, 1);
});
// myCharacters is now { "Charles Condomine", "George", "TomJohn" }
c.Cocoa中使用block
@"String 21",
@"string 12",
@"String 11",
@"String 02" ];
static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch |
NSWidthInsensitiveSearch | NSForcedOrderingSearch;
NSLocale *currentLocale = [NSLocale currentLocale];
//比较器为代码块
NSComparator finderSortBlock = ^(id string1, id string2) {
NSRange string1Range = NSMakeRange(0, [string1 length]);
return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale];
};
NSArray *finderSortArray = [stringsArray sortedArrayUsingComparator:finderSortBlock];
NSLog(@"finderSortArray: %@", finderSortArray);
/*
Output:
finderSortArray: (
"string 1",
"String 02",
"String 11",
"string 12",
"String 21"
)
*/
d.__block变量
首先看简单的例子
int x = 123;
void (^printXAndY)(再谈序列化 - K战神 阅读原文»
目录:
- 序列化、反序列化
类型序列化的前提
格式化器序列化原理
控制序列化和反序列化
一、序列化
序列化是将一个对象转换成一个字节流的过程。
反序列化是将一个字节流转回一个对象的过程。
--------序列化----------
对象:p
载体:序列化后的字节流载体 ms
格式化器:序列化工作的工人 formatter
序列化:将 p 进行序列化成字节流 ms
-----反序列化------
formatter.Deserialize(ms);
实例应用之一:深拷贝
internal class Product:ICloneable
{
public string Name { get; set; }
public int Age { get; set; }
public NumberFlag Number { get; set; }
public object Clone()
{
return this.MemberwiseClone();
}
public Product DeepClone()
{
using (System.IO.Stream ms = new System.IO.MemoryStream())
{
System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
formatter.Context = new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Clone);
formatter.Serialize(ms, this);
ms.Position = 0;
return formatter.Deserialize(ms) as Product;
}
}
}
[Serializable]
internal class NumberFlag
{
public string Num { get; set; }
}
首先我们了解浅拷贝,拷贝的对象中的引用类型的值的改变会互相影响:
{
Name = "1",
Age = 1,
Number = new NumberFlag() { Num="01"}
};
var p2 = p1.Clone() as Product;
if (p2 != null)
{
p2.Number.Num = "22";
Console.WriteLine("p1 Number:{0}.",p1.Number.Num);
Console.WriteLine("p2 Number:{0}.",p2.Number.Num);
Console.ReadKey();
}
但是,深拷贝能够解决以上问题:
{
Name = "1",
Age = 1,
Number = new NumberFlag() { Num="01"}
};
var p2 = p1.DeepClone();
if (p2 != null)
{
p2.Number.Num = "22";
Console.WriteLine("p1 Number:{0}.",p1.Number.Num);
Console.WriteLine("p2 Number:{0}.",p2.Number.Num);
Console.ReadKey();
}
二、类型序列化的前提
类型默认是不可以序列化的,需要加上特性 [Serializable]
SerializableAttribute 这个特性只能应用于:引用类型(class)\值类型(struct)\枚举类型(enum)\委托类型(delegate).
也不能被子类所继承。
public class Phone
{
}
[Serializable]
public class iPhone:Phone
{
}
三、格式化器序列化原理
为了实现格式化器的工作,FCL封装了一个:受保护、不可实例化的类--FormatterServices
-----格式化器,序列化-------
1、格式化器调用 FormatterServices 的 GetSerializableMembers 方法,这个方法通过反射,返回当前类的成员数组。
没有评论:
发表评论