2015年7月5日星期日

(8/18)重学Standford_iOS7开发_协议、block、动画_课程笔记 - NSLogMeng

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
(8/18)重学Standford_iOS7开发_协议、block、动画_课程笔记 - NSLogMeng  阅读原文»

第八课:

  1、协议

    另一种安全处理id类型的方式如:id <MyProtocol> obj

    a.声明

//协议一般放于.h文件中或者在类的.h文件中

@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.在类中实现协议

#import “Foo.h”
@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.用途

      ①委托

      ②数据源

//UI与controller盲通信的方式
@property (nonatomic, weak) id <UISomeObjectDelegate> delegate;
@property (nonatomic, weak)
id <UISomeObjectDataSource> dataSource;

      ③动画

  2、Block(来源于API文档)

    实际上为一段代码块,类似于C语言中的函数指针

    a.声明

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};
//int 为block返回值
//^表示为此为代码块
//myBlock为此代码块名
//int 为参数类型
//等号右边为block实现

    block可以使用和他的同一范围内声明的变量,使用block与使用C函数类似

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
return num * multiplier;
};

printf(
"%d", myBlock(3));
// prints "21"

    b.直接使用block

      block可以省略block声明直接使用

char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" };

//直接使用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

NSArray *stringsArray = @[ @"string 1",
@"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

List<string> p = new List<string>() { "Sun", "Mon", "Star" };

载体:序列化后的字节流载体 ms

System.IO.MemoryStream ms = new System.IO.MemoryStream();

格式化器:序列化工作的工人 formatter

System.Runtime.Serialization.Formatters.Binary.BinaryFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

序列化:将 p 进行序列化成字节流 ms

formatter.Serialize(ms, p);

-----反序列化------

ms.Position=0;

formatter.Deserialize(ms);

实例应用之一:深拷贝

[Serializable]
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; }
}


首先我们了解浅拷贝,拷贝的对象中的引用类型的值的改变会互相影响:

Product p1 = new Product()
{
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();
}

但是,深拷贝能够解决以上问题:

Product p1 = new Product()
{
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).

也不能被子类所继承。

[Serializable]
public class Phone
{

}

[Serializable]
public class iPhone:Phone
{

}

三、格式化器序列化原理

为了实现格式化器的工作,FCL封装了一个:受保护、不可实例化的类--FormatterServices

System.Runtime.Serialization.FormatterServices

-----格式化器,序列化-------

1、格式化器调用 FormatterServices 的 GetSerializableMembers 方法,这个方法通过反射,返回当前类的成员数组。

没有评论:

发表评论