最近经历了一些事情,越发地体会到了在生活面前自己的无力感。
努力前行的路上,不怕有困难,而怕身边没有志同道合的伙伴。多么希望他人能明白自己的用心,却发现每个人都困在自己的一隅,伸手想拉一把,却发现井中人倒并不想上来。
明明尽力补救,却眼睁睁看着它一步一步朝着不好的方向发展,心急如焚,却又无可奈何。
record
最近经历了一些事情,越发地体会到了在生活面前自己的无力感。
努力前行的路上,不怕有困难,而怕身边没有志同道合的伙伴。多么希望他人能明白自己的用心,却发现每个人都困在自己的一隅,伸手想拉一把,却发现井中人倒并不想上来。
明明尽力补救,却眼睁睁看着它一步一步朝着不好的方向发展,心急如焚,却又无可奈何。
让那歌喉最响亮的鸟雀,
飞上独立的凤树的枝头,
宣布讣告,把哀乐演奏,
一切飞禽都和着拍子跳跃。
可是你叫声刺耳的狂徒,
你魔鬼的邪恶的信使,
死神的忠实的信士,
千万别走近我们的队伍。
任何专横跋扈的暴徒,
都不容走近我们的会场,
只除了鹰,那羽族之王:
葬礼的尊严不容玩忽。
让那身穿着白色袈裟,
懂得死亡之曲的牧师,
唱出死神来临的挽诗,
并由他领着作弥撒。
还有你寿长过人的乌鸦,
也必须参加哭丧的队伍,
你生来穿着黑色的丧服,
开口就像哭不用作假。
接着他们唱出送丧的哀辞,
爱情和忠贞已经死亡;
凤和鸠化作一团火光
一同飞升,离开了尘世。
它们是那样彼此相爱,
仿佛两者已合为一体;
分明是二,却又浑然为一:
是一是二,谁也难猜。
两颗心分开,却又在一起;
斑鸠虽和它的皇后分开,
它们之间却并无距离存在:
这情景只能说是奇迹。
爱情在它俩之间如电光闪灼,
斑鸠借着凤凰的眼睛,
就能清楚地看见自身:
彼此都认为对方是我。
物性仿佛已失去规矩,
本身竟可以并非本身,
形体相合又各自有名,
两者既分为二又合为一。
理智本身也无能为力,
它明明看到合一的分离,
二者全不知谁是自己,
这单一体原又是复合体。
它不禁叫道,“多奇怪,
这到底是二还是一!
这情景如果长存下去,
理智将变作爱情的奴才。”
因此它唱出一首哀歌,
敬献给凤凰和斑鸠,
这爱情的明星和旗手,
吊唁它们的悲惨结果。
哀歌
美、真、至上的感情,
如此可贵,如此真纯,
现在竟一同化作灰烬。
凤巢现在已不复存在;
那斑鸠的忠贞情怀,
此一去,永远难再。
也未留下后代儿孙——
这并非因它们身体有病,
而是因为婚后仍童身。
从今后,再说真,是谎,
再有美,不过是假相,
真和美已被埋葬。
不真不美的也别牢骚,
这骨灰瓶可以任你瞧,
这两只死鸟正为你默祷。
—莎士比亚
哲学上说“存在即是合理”,warning的必要在于它能提示开发者潜在的问题,让我们尽快调整从而提高代码质量。
另一方面,如果原有工程代码量过大,warning动则上千上万,都说互联网迭代开发基本上等于高速上换轮胎,哪还有时间去抽根烟,所以在实际开发过程中不可能有专门的时间来去除warning,而又不能完全无视warning,毕竟,warning的存在是我们优化代码提高代码健壮性和稳定性的契机。
既不能熟视无睹,也无法一蹴而就,那怎么办?虽然没法立马根除,但根据“化大为小”的原则,我们可以逐一击破。
Xcode工程中一般都会引用第三方工程,比如pod,如果是以源码的形式引入,则很可能随着pod的增加,warning数会剧增,而这部分warning其实我们不一定有足够的控制力,即使去修改其中的代码也要考虑到后期每次升级都需要重新再来一次,过于耗费人力。去除warning只是方法,我们的目的是提高自身代码的质量,所以可以直接屏蔽第三方pod的warning。如果某些pod是公司内部的,可以推动pod的负责人去优化。
Cocoapods提供了
inhibit_all_warnings!
的指令,可以直接屏蔽所有第三方pod的warning,同时也提供了
pod 'ReactiveCocoa', '~> 2.1', :inhibit_warnings => true
的配置项,可以屏蔽某一三方库的warning。
但在Cocoapods 1.2.1版本都无效,打开pod install后的pod工程配置,inhibit_all_warnings还是NO。
但我们可以用post_install钩子直接修改各个pod工程的配置
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['GCC_WARN_INHIBIT_ALL_WARNINGS'] = 'YES'
end
end
end
同时,为了更好地发挥warning的作用,我们还可以让Xcode更好地产生warning。
其他还有很多设置
Wall
Wbad-function-cast
Wcast-align
Wconversion
Wdeclaration-after-statement
Wdeprecated-implementations
Wextra
Wfloat-equal
Wformat=2
Wformat-nonliteral
Wfour-char-constants
Wimplicit-atomic-properties
Wmissing-braces
Wmissing-declarations
Wmissing-field-initializers
Wmissing-format-attribute
Wmissing-noreturn
Wmissing-prototypes
Wnested-externs
Wnewline-eof
Wold-style-definition
Woverlength-strings
Wparentheses
Wpointer-arith
Wredundant-decls
Wreturn-type
Wsequence-point
Wshadow
Wshorten-64-to-32
Wsign-compare
Wsign-conversion
Wstrict-prototypes
Wstrict-selector-match
Wswitch
Wswitch-default
Wswitch-enum
Wundeclared-selector
Wuninitialized
Wunknown-pragmas
Wunreachable-code
Wunused-function
Wunused-label
Wunused-parameter
Wunused-value
Wunused-variable
Wwrite-strings
根据需要添加。
感兴趣的可以看看 这篇文章 。
我们屏蔽了第三方pod的warning,同时增加了主工程的warning,目的都是一个:更有针对性地提升代码的健壮性和稳定性。
山岭迈入白色之中
人和星辰
伤心地望着我,我令他们失望
火车留下一趟呼出的气
哦,慢腾腾的
马,锈色
马蹄,悲哀的铃声
早晨越来越暗
整整一早晨
一朵花已经离去
我的骨头抓住一片儿寂静,远处的
田野溶化了我的心
他们威胁我
要我穿过,去一片没有
星辰,没有父亲的天空,一泓黑水
—西尔维亚•普拉斯
我就要起身走了,到茵尼斯弗利岛,
造座小茅屋在那里,枝条编墙糊上泥;
我要养上一箱蜜蜂,种上九行豆角,
独住在蜂声嗡嗡的林间草地。
那儿安宁会降临我,安宁慢慢儿滴下来,
从晨的面纱滴落到蛐蛐歇唱的地方;
那儿半夜闪着微光,中午染着紫红光彩,
而黄昏织满了红雀的翅膀。
我就要起身走了,因为从早到晚从夜到朝
我听得湖水在不断地轻轻拍岸;
不论我站在马路上还是在灰色人行道,
总听得它在我心灵深处呼唤。
—叶芝
最近看到新闻http://daily.zhihu.com/story/9310547说workflow被苹果收购并免费了,之前就听说workflow是iOS平台上的效率神奇,于是第一时间下载试用。
一直都痴迷于试用工具和流程提升效率,无论是工作、学习还是娱乐:使用shell脚本一键发布、通过BetterTouchTool使用手势触发各种快捷键以及配合Keyboard Maestro设置的快捷键、一键下载Youtube上的视频播单,包括之前整理的个人信息系统,以及自己开发的Arsos和Afred的workflow以及Popclip的extension。
提升效率就是延长生命
每个效率工具都足以写一整篇博客来介绍,以下就列举下一些我常用的工具,排名不分先后
另外还有iOS上的IFTTT,平时用来看天气和球赛结果还是不错的。
无径之林 常有情趣
无人之岸 几多惊喜
无人驻足 是为桃源
岸畔崖间 鼓涛为乐
吾爱世人 自然甚之
—拜伦
最近事情太多了,偷懒把15年的读书笔记发上来充个数。
不属于23种设计模式的任何一种,本身就是一种设计模式
类似于命令模式,NSInvocation是一种更为完备的命令模式
bundle本身就是一种设计模式,类似facade
In the C programming language and languages derived from it like Objective-C and C++, compilers and linkers convert explicit function calls in program source code into machine language jumps to code at predetermined fixed addresses in memory.The conversion of code to fixed addresses in sometimes called binding
mac开发中还有一种binding是利用KVO做双向绑定,具体实现原理不清楚,但有类似的ios开源库(Bind),可以研究下
NSProxy
UIView的子类、category
Model View Controller
分离成两个步骤后,有desinated initializer和非desinated initializer,方便创建非desinated initializer
If you find yourself contemplating the creation of Template Methods in code intended for reuse, first consider Delegates. In many cases, Delegates provide a more flexible alter- native to Template Methods.
One very important aspect of this power is the fact that this function allows a developer to use an object that was unknown to the compiler and linker when the application was built
The NSArray and NSMutableArray classes store ordered collections of object refer- ences.The NSDictionary and NSMutableDictionary classes store associations of keys and values for rapid retrieval.The NSSet and NSMutableSet classes store unordered col- lections of unique object references; each object can be referenced at most once in any particular set. Finally, NSCountedSet, a subclass of NSMutableSet, provides an unordered collection, but it allows multiple references to the same object within one collection.
NSOrderedSet NSMutableOrderedSet
一个通过继承(NSEnumerator),一个通过协议(NSFastEnumeration)
The Invocation pattern and the NSInvocation class provide a more complete implementation of late binding of messages than the simple –performSelector: method. NSInvocation can store messages that have nonobject return types or require complex arguments.
An Action is really just a variable selector, and the target is just an anonymous object
Methods like NSData’s -(void)getBytes:(void )aBuffer return values by reference because the number of bytes that will be returned can’t be determined at compile time. Other examples of get methods include NSArray’s -(void)getOb- jects:(id )aBuffer, NSString’s -(void)getCharacters:(unichar )aBuffer, and NSValue’s -(void)getValue:(void )aBuffer. In each case, the size of the value copied into the referenced memory is variable.Another reason for returning values by ref- erence is to enable the return of more than one value from a single method.A good ex- ample of that is NSColor’s -(void)getRed:(CGFloat )red green:(CGFloat )green blue:(CGFloat )blue alpha:(CGFloat )alpha method, which returns four floating point values by reference.
Conditional Encoding
Classes exist to encapsulate information about instances and provide a single inter- face for creating instances. Using an instance of MYGameHighScoreManager to manage scores and using the MYGameHighScoreManager class itself to encapsulate access to the in- stance is the cleanest way to achieve the goals of flexibility and maintainability.
The object that sends a message to a notification center doesn’t need to know what observers exist or how many observers ultimately receive the notification. Similarly, the observers don’t necessarily need to know where notifications originate
Use the Notification pattern when anonymous objects need to passively observe and react to important events. In contrast, use the Delegates pattern when anonymous objects need to actively influence events as they happen.
Delegates simplify the customization of object behavior while minimizing coupling be- tween objects
Subclassing statically establishes the relationship between the subclass and its superclass at compile time. In many cases, runtime flexibility is desired. For example, constraints on the resizing behav- ior of a window might change based on user actions at runtime
Data sources are similar to delegates, but they play a different role. Delegates react to changes or control other objects.A data source provides data to another object whenever needed. Delegates are always optional; the object that uses a delegate falls back to default behavior if there is no delegate assigned.An object that uses a data source may not be functional without a valid data source to supply data. For example, Cocoa’s NSTableView class retrieves data as needed from a data source. Using a data source provides several advantages. First and most importantly, using a data source preserves the separation of subsystems in the Model-View-Controller pattern.The graphical table drawing and editing features of NSTableView clearly belong in the View subsystem. Calculation, retrieval, and storage of the data values to be displayed are clearly part of the Model subsystem.The calculations and storage of data remains the same even if the mechanism used to display the data changes.The same Model data could be displayed in a pie chart or output to a file or sent to a printer.The object acting as a data source for an instance of NSTableView is typically part of the Controller subsystem.The data source responds to the NSTableView’s requests for data by retrieving the data from the Model. NSTableView is decoupled from details regarding the retrieval of data from the Model. Similarly, classes in the Model subsystem have no coupling to the View objects that dis- play data. Using a data source has the added advantage of enabling efficient data processing and memory usage. For example, even if a table has a million rows, at most a few dozen rows can be seen on the screen at once. NSTableView only asks its data source for the data needed to display the currently visible rows. If the Model subsystem needs to calculate the data or the data must be fetched over a network from a database, there is no need to cal- culate or fetch a million rows of data at once. Like a delegate, the data source object is not retained by the object that uses it. A single object acting as a data source may provide data to any number of objects.Apple identifies the messages that will be sent to a data source in the class documentation for the classes that require a data source. Just like delegate methods, there is typically an informal proto- col that declares the methods a data source must implement.
Any instance variable with type id and a name that doesn’t start with an underscore character is automatically considered an outlet. In addi- tion, any instance variable that is a pointer to an object and includes the IBOutlet macro in its declaration is treated as an outlet.
The IBOutlet macro is defined in NSNibDeclarations.h, which is part of Cocoa’s Application Kit framework, and the C preprocessor replaces it with a single space charac- ter whenever it’s encountered in source code. IBOutlet doesn’t change the meaning of compiled code at all. It is just a hint to Interface Builder that identifies outlets with types more specific than id.When a specific type is declared, Interface Builder will respect it and use that information to limit what types of objects may be connected to that outlet.
The IBAction type is actually a preprocessor macro that evaluates to the void type.
With regard to coupling, the MYPlayerController class knows about the MYSongPlayer object in the Model and is therefore coupled to the Model, but the Model knows nothing about the Controller subsystem.The MYPlayerController instance also has outlets that are con- nected toView objects.The Controller is slightly coupled to theView but knows very lit- tle about theView objects with which it communicates.TheView has no dependence on the Controller.The buttons and slider have targets defined with type id, which means they could be connected to any objects that respond to the assigned action messages.

As a user works with an application, Cocoa automatically tracks where the user’s focus is.The window currently receiving keyboard input is known as the “key” window.The currently focused document is known as the “main” window. Usually a user is working directly in the document, so the key and main windows are the same. Sometimes the user’s focus is actually on two windows, however. For example, in a multidocument appli- cation with utility panels, the user might be focused on a particular document while entering something into a utility panel.The input to the utility panel is expected to mod- ify the focused document in some way. In this case, the utility panel would be the key window, while the document it affects is the main window
Incoming keyboard and mouse events are converted to NSEvent objects by the NSApplication object and then dispatched to the correct responder object by passing them down a Responder Chain. For a keyboard events and mouse moved events, the first responder of the key window is the head of the chain. For mouse clicks, the most deeply nested view directly under the mouse is the head. If a responder doesn’t want to handle the event, then it will pass the event on to the next responder in the chain until either an object handles the event or the event reaches the end of the chain.
In addition to conforming to the NSCopying protocol, objects used as keys in a dictionary must implement the -isEqual: and -hash methods so that any two objects that are considered equal by the -isEqual: method also have the same hash value.The -isEqual: and -hash methods are declared in the NSObject class, which provides basic implementations using the addresses of objects. In other words, two objects are equal if they have the same address, and the -hash value is computed from the address.
The key value system allows pro- grams to interact with objects as if every object is a dictionary that associates its properties with string keys
KeyValue Coding provides a way for scripting languages to access the values stored in objects at runtime based on the string name of the value. Perhaps more importantly, Key Value Coding is the foundation for Cocoa bindings technology. Key Value Coding applies the Associative Storage pattern to every Cocoa object so that object instance variables or accessors are selected at runtime via string keys.
KVC/KVO is a variation of the Associative Storage pattern, which lets you access the properties of ob- jects as if every object were a simple dictionary of key/value pairs
One point of confusion for many developers is in how messages are named. Each name has two parts, the selector and the method signature. Both parts are required to properly configure NSInvocation objects. A selector is the message’s name without any type infor- mation, for example “countOfObjectsOfType:” is a selector. Objective-C also has the data type SEL, which is a unique identifier representing a selector.The Objective-C direc- tive @selector() can be used to obtain a SEL.
Most programmers consider the selector to be the same thing as the message name, and in most cases this is fine. However, selectors do not provide any type information. To build a complete message, the types of each argument and the return value’s type need to be known.This type information is known as a method signature.The class NSMethodSignature encapsulates this information
Invocations package up an Objective-C method so that it can be handled as if it were an object
}
selector(用sel表示)
tellPerson: @selector(tellPerson:)
method signature (用NSMethodSignature表示)
id id
NSString *receivingString = [receiver stringValue];
NSString *messageString = [message titleOfSelectedItem];
SEL selector = NSSelectorFromString(messageString);
NSMethodSignature *methodSignature = [receivingString methodSignatureForSelector:selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
[invocation setTarget:receivingString]; // argument 0 is "self"
[invocation setSelector:selector]; // argument 1 is "_cmd"
int numberOfArguments = [[message selectedItem] tag];
if (numberOfArguments > 0)
{
NSString *argumentString1 = [argument1 stringValue];
[invocation setArgument:&argumentString1 atIndex:2];
if (numberOfArguments > 1)
{
NSString *argumentString2 = [argument2 stringValue];
[invocation setArgument:&argumentString2 atIndex:3];
}
}
[invocation invoke];
void *returnValue = NULL;
[invocation getReturnValue:&returnValue];
const char *returnType = [methodSignature methodReturnType];
if (returnType) {
switch (returnType[0]) {
case ‘@':
[result setObjectValue:(id)returnValue]; break;
case ‘i':
[result setIntValue:(int)returnValue]; break;
default: break;
}
}
The most essential feature of prototype objects is that they can be copied
There may be a lot of NSNumber instances in use at any one time in a Cocoa program. Cocoa optimizes storage for NSNumber instances by sharing them. Each time you call NSNumber numberWithInt:0;, you are likely to get the same instance returned. Cocoa keeps a cache of recently or frequently used NSNumber instances.When you ask for a new NSNumber that stores the same value as a cached instance, the cached instance is returned instead of a new instance
The patterns in Part IV hide complexity and implementation details so programmers can focus on solving problems.
编程是为了解决问题,不要被技术细节困住,专注于解决问题
iOS

Mac OS

class cluster

多例模式:可以用这个模式设计内存池
The philosophy is to keep common interaction simple while making complex interaction possible
The Proxy pattern allows messages to be sent to an object that is separated from the mes- sage’s sender by time or space. Proxies can also control access to or alter the behavior of other objects. Forwarding simplifies the capture of messages as invocations so that they can be resent, delayed, repeated, stored, or altered.
A proxy can simulate a category with instance variables by defining its own variables and methods and then forwarding everything else to the real object.
Furthermore, when a category overrides an object’s existing methods, it has no easy way to access the original method, but a proxy can.
给个例子啊。。。
Proxies are also able to simulate multiple inheritance by for- warding messages to multiple other objects, creating a form of composite object.
The Manager pattern is a hybrid and a generalization of other patterns such as Singleton, Façade, and Controllers.
In custom code, a manager should be used when a class is needed for managing instances of other classes, especially when uniqueness is required.


When input data becomes available, the run loop translates the data into events and sends Objective-C messages to various objects to process the events.
The key window receives key- board events.The main window is the window that is affected by actions in the key win- dow.The key window and the main window are usually the same, but in some cases they might be different
The first view to receive an event-processing message depends on the type of the event.The first mouse-down event within a window that is not the key window is usually consumed by the window itself to make the window into the key window and bring it to the front.This behavior can be modified in several ways. For example, a subclass of NSView can override the - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent method to return YES based on the mouse event. Returning YES means that the view is able to use the first mouse click in an inactive window. NSWindow sends mouse-down and mouse-move event messages to the top-most view under the mouse. Subviews are drawn after their superview.The top-most view under the mouse is therefore usually the most deeply nested view under the mouse. Mouse-move events occur frequently and are seldom used. NSWindow does not send mouse move event messages to views by default. If a subclass of NSView needs to receive mouse-move events, it must tell NSWindow to send them. NSWindow’s -(void)setAcceptsMouseMovedEvents: (BOOL)acceptMouseMovedEvents method is used to tell the window to send mouse- move event messages to views. Mouse-drag and mouse-up event messages are sent to the view that received the corresponding mouse-down event. Keyboard event messages are sent to the first responder within the window.The NSView class implements the - (BOOL)acceptsFirstResponder method to always return NO. As a result, most views never become the first responder within a window.
Objective-C mes- sages that have one object argument are called actions
The role of the shared NSApplication object in the target-action implementation is important. If the target of a user interface element is specified, the shared application ob- ject just sends the action message to the target directly. However, if no target is specified (the to: argument is nil), -sendAction:to:from: uses the Responder Chain to select the object that receives the action message. Setting the target of a user interface element to nil makes the target context-sensitive. If the to: argument to -sendAction:to:from: is nil, NSApplication searches the Responder Chain for an object that can respond to the action message.The search begins with the first responder in the key window. If the first responder can’t respond to the ac- tion message, the next responder is checked and so on until the key window itself is reached. After the key window gets a chance, the key window’s delegate is checked. If the key window’s delegate can’t respond to the action message, and the main window is dif- ferent from the key window, the first responder in the main window is checked.The search for an object that responds to the action continues up the main window’s Respon- der Chain to the main window itself and then the main window’s delegate. If no target has been found, the application object is tried. Finally, if the application object can’t re- spond to the action, the application object’s delegate is given a chance
Inside NSObject’s default implementation of the NSKeyValueObserving informal pro- tocol, -willChangeValueForKey: and -didChangeValueForKey: are implemented to send messages to registered observers before and after the property value changes.
It’s not necessary to explicitly call -willChangeValueForKey: and -didChangeValueForKey: within correctly named Accessor methods.When you use Objective-C 2.0’s @synthesize directive to generate Accessor method implementations, the details are handled for you. Even if you hand-write Accessor methods, Cocoa provides auto- matic support for KeyValue Observing through a little bit of Objective-C runtime manipu- lation briefly described at http://developer.apple.com/documentation/Cocoa/Conceptual/ KeyValueObserving/Concepts/KVOImplementation.html.At runtime,Cocoa is able to replace your implementation of each Accessor method with a version that first calls -willChangeValueForKey:, then calls your implementation, and finally calls -didChangeValueForKey:. When Key Value Coding’s -(void)setValue:(id)value forKey:(NSString )key or -(void)setValue:(id)value forKeyPath:(NSString )keyPath methods are used to modify an observed property, the appropriate Accessor methods (if any) are called, and the Accessor methods take care of calling -willChangeValueForKey: and -did- ChangeValueForKey:. If there aren’t any available Accessor methods, -setValue:forKey: and -setValue:forKeyPath: call -willChangeValueForKey: and -didChangeValueForKey: directly. In summary, you only need to explicitly call -willChangeValueForKey: and -didChangeValueForKey: if you change the value of an observed property without using Key Value Coding and without using an appropriately named Accessor method.
brew install redis
redis-server
brew services start redis
redis-cli
redis-cli -h {redis_host} -p {redis_port}
info keyspace
select 2
keys *
set varname value1
get varname
flushdb // 清除当前数据库的所有keys
flushall // 清除所有数据库的所有keys