﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-tommy</title><link>http://www.cppblog.com/tommy/</link><description>It's hard to tell the world we live in is either a reality or a dream</description><language>zh-cn</language><lastBuildDate>Sun, 05 Apr 2026 16:31:19 GMT</lastBuildDate><pubDate>Sun, 05 Apr 2026 16:31:19 GMT</pubDate><ttl>60</ttl><item><title>使用 Poco 对 Mixpanel 发出的数据报告程序</title><link>http://www.cppblog.com/tommy/archive/2015/01/24/209631.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Sat, 24 Jan 2015 14:48:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2015/01/24/209631.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/209631.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2015/01/24/209631.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/209631.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/209631.html</trackback:ping><description><![CDATA[StatService.h<br />
<div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->#pragma&nbsp;once<br />
<br />
<span style="color: #0000FF; ">class</span>&nbsp;StatService&nbsp;{<br />
<span style="color: #0000FF; ">public</span>:<br />
&nbsp;&nbsp;&nbsp;&nbsp;StatService();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;trackPageView(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;&amp;page);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;trackEvent(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;&amp;eventName,&nbsp;map&lt;<span style="color: #0000FF; ">string</span>,&nbsp;<span style="color: #0000FF; ">string</span>&gt;&nbsp;&amp;props);&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
<span style="color: #0000FF; ">private</span>:<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;getUrl(<span style="color: #0000FF; ">string</span>&nbsp;url);<br />
};</div>
<br />StatService.cpp<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include&nbsp;"StatService.h"<br />#include&nbsp;"GlobalConfig.h"<br />#include&nbsp;&lt;Poco/Net/HTTPClientSession.h&gt;<br />#include&nbsp;&lt;Poco/Net/NetworkInterface.h&gt;<br />#include&nbsp;&lt;Poco/Net/HTTPRequest.h&gt;<br />#include&nbsp;&lt;Poco/Net/HTTPResponse.h&gt;<br />#include&nbsp;&lt;Poco/StreamCopier.h&gt;<br />#include&nbsp;&lt;Poco/Path.h&gt;<br />#include&nbsp;&lt;Poco/URI.h&gt;<br />#include&nbsp;&lt;Poco/Exception.h&gt;&nbsp;<br />#include&nbsp;&lt;Poco/Base64Encoder.h&gt;<br /><br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;Poco::Net;<br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;Poco;<br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><br />StatService::StatService()&nbsp;{<br />}<br /><br /><span style="color: #0000FF; ">string</span>&nbsp;GetIP()&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;NetworkInterface::NetworkInterfaceList&nbsp;list&nbsp;=&nbsp;NetworkInterface::list();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(NetworkInterface::NetworkInterfaceList::iterator&nbsp;i&nbsp;=&nbsp;list.begin();&nbsp;i&nbsp;!=&nbsp;list.end();&nbsp;++i)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NetworkInterface&nbsp;nt&nbsp;=&nbsp;*i;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IPAddress&nbsp;addr&nbsp;=&nbsp;nt.address();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(!addr.isLoopback())&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;addr.toString();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;"";<br />}<br /><br /><span style="color: #0000FF; ">void</span>&nbsp;StatService::trackPageView(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;&amp;page)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;GlobalConfig&nbsp;*gConfig&nbsp;=&nbsp;GlobalConfig::GetInstance();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;eventName&nbsp;=&nbsp;"VisitPage";<br />&nbsp;&nbsp;&nbsp;&nbsp;stringstream&nbsp;ss;<br />&nbsp;&nbsp;&nbsp;&nbsp;ss&nbsp;&lt;&lt;&nbsp;"{"&nbsp;&lt;&lt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\"<span style="color: #0000FF; ">event</span>\":\""&nbsp;&lt;&lt;&nbsp;eventName&nbsp;&lt;&lt;&nbsp;"\","&nbsp;&lt;&lt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\"properties\":&nbsp;{"&nbsp;&lt;&lt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\"page\":\""&nbsp;&lt;&lt;&nbsp;page&nbsp;&lt;&lt;&nbsp;"\","&nbsp;&lt;&lt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;"distinct_id"&nbsp;and&nbsp;"token"&nbsp;are<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;special&nbsp;properties,&nbsp;described&nbsp;below.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\"distinct_id\":"&nbsp;&lt;&lt;&nbsp;"\""&nbsp;&lt;&lt;&nbsp;GetIP()&nbsp;&lt;&lt;&nbsp;"\","&nbsp;&lt;&lt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\"token\":\""&nbsp;&lt;&lt;&nbsp;gConfig-&gt;stat_token()&nbsp;&lt;&lt;&nbsp;"\"";<br />&nbsp;&nbsp;&nbsp;&nbsp;ss&nbsp;&lt;&lt;&nbsp;"}}";<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">encode</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;std::ostringstream&nbsp;base64Str;<br />&nbsp;&nbsp;&nbsp;&nbsp;Base64Encoder&nbsp;encoder(base64Str);<br />&nbsp;&nbsp;&nbsp;&nbsp;encoder&nbsp;&lt;&lt;&nbsp;ss.str();<br />&nbsp;&nbsp;&nbsp;&nbsp;encoder.close();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">cout&nbsp;&lt;&lt;&nbsp;base64Str.str()&nbsp;&lt;&lt;&nbsp;endl;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;ss.str()&nbsp;&lt;&lt;&nbsp;endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;ostringstream&nbsp;url;<br />&nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;&lt;&lt;&nbsp;gConfig-&gt;stat_endpoint()&nbsp;&lt;&lt;&nbsp;"?data="&nbsp;&lt;&lt;&nbsp;base64Str.str();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;sUrl&nbsp;=&nbsp;url.str();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">cout&nbsp;&lt;&lt;&nbsp;sUrl&nbsp;&lt;&lt;&nbsp;endl;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;sUrl.erase(remove_if(sUrl.begin(),&nbsp;sUrl.end(),&nbsp;isspace),&nbsp;sUrl.end());<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">replaceAll(sUrl,&nbsp;"\n",&nbsp;"$");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">kick&nbsp;off</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;getUrl(sUrl);&nbsp;&nbsp;&nbsp;&nbsp;<br />}<br /><br /><br /><span style="color: #0000FF; ">void</span>&nbsp;replaceAll(std::<span style="color: #0000FF; ">string</span>&amp;&nbsp;str,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;std::<span style="color: #0000FF; ">string</span>&amp;&nbsp;from,&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;std::<span style="color: #0000FF; ">string</span>&amp;&nbsp;to)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(from.empty())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>;<br />&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;start_pos&nbsp;=&nbsp;0;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>((start_pos&nbsp;=&nbsp;str.find(from,&nbsp;start_pos))&nbsp;!=&nbsp;std::<span style="color: #0000FF; ">string</span>::npos)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str.replace(start_pos,&nbsp;from.length(),&nbsp;to);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start_pos&nbsp;+=&nbsp;to.length();&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;In&nbsp;case&nbsp;'to'&nbsp;contains&nbsp;'from',&nbsp;like&nbsp;replacing&nbsp;'x'&nbsp;with&nbsp;'yx'</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><span style="color: #0000FF; ">void</span>&nbsp;StatService::trackEvent(<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;&amp;eventName,&nbsp;map&lt;<span style="color: #0000FF; ">string</span>,<span style="color: #0000FF; ">string</span>&gt;&nbsp;&amp;props)&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;GlobalConfig&nbsp;*gConfig&nbsp;=&nbsp;GlobalConfig::GetInstance();<br />&nbsp;&nbsp;&nbsp;&nbsp;stringstream&nbsp;ss;<br />&nbsp;&nbsp;&nbsp;&nbsp;ss&nbsp;&lt;&lt;&nbsp;"{"&nbsp;&lt;&lt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\"<span style="color: #0000FF; ">event</span>\":\""&nbsp;&lt;&lt;&nbsp;eventName&nbsp;&lt;&lt;&nbsp;"\","&nbsp;&lt;&lt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\"properties\":&nbsp;{"&nbsp;&lt;&lt;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;"distinct_id"&nbsp;and&nbsp;"token"&nbsp;are<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;special&nbsp;properties,&nbsp;described&nbsp;below.</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\"distinct_id\":"&nbsp;&lt;&lt;&nbsp;"\""&nbsp;&lt;&lt;&nbsp;GetIP()&nbsp;&lt;&lt;&nbsp;"\","&nbsp;&lt;&lt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"\"token\":\""&nbsp;&lt;&lt;&nbsp;gConfig-&gt;stat_token()&nbsp;&lt;&lt;&nbsp;"\"";<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">plugin&nbsp;in&nbsp;properties&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(map&lt;<span style="color: #0000FF; ">string</span>,<span style="color: #0000FF; ">string</span>&gt;::const_iterator&nbsp;i&nbsp;=&nbsp;props.cbegin();&nbsp;i&nbsp;!=&nbsp;props.cend();&nbsp;++i)&nbsp;{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ss&nbsp;&lt;&lt;&nbsp;",\""&nbsp;&lt;&lt;&nbsp;i-&gt;first&nbsp;&lt;&lt;&nbsp;"\":\""&nbsp;&lt;&lt;&nbsp;i-&gt;second&nbsp;&lt;&lt;&nbsp;"\"";<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;ss&nbsp;&lt;&lt;&nbsp;"}}";<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">encode</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;std::ostringstream&nbsp;base64Str;<br />&nbsp;&nbsp;&nbsp;&nbsp;Base64Encoder&nbsp;encoder(base64Str);<br />&nbsp;&nbsp;&nbsp;&nbsp;encoder&nbsp;&lt;&lt;&nbsp;ss.str();<br />&nbsp;&nbsp;&nbsp;&nbsp;encoder.close();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">cout&nbsp;&lt;&lt;&nbsp;base64Str.str()&nbsp;&lt;&lt;&nbsp;endl;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;ss.str()&nbsp;&lt;&lt;&nbsp;endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;ostringstream&nbsp;url;<br />&nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;&lt;&lt;&nbsp;gConfig-&gt;stat_endpoint()&nbsp;&lt;&lt;&nbsp;"?data="&nbsp;&lt;&lt;&nbsp;base64Str.str();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">string</span>&nbsp;sUrl&nbsp;=&nbsp;url.str();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">cout&nbsp;&lt;&lt;&nbsp;sUrl&nbsp;&lt;&lt;&nbsp;endl;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;sUrl.erase(remove_if(sUrl.begin(),&nbsp;sUrl.end(),&nbsp;isspace),&nbsp;sUrl.end());<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">replaceAll(sUrl,&nbsp;"\n",&nbsp;"$");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">kick&nbsp;off</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;getUrl(sUrl);<br />}<br /><span style="color: #0000FF; ">void</span>&nbsp;StatService::getUrl(<span style="color: #0000FF; ">string</span>&nbsp;url)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;URI&nbsp;uri(url);<br />&nbsp;&nbsp;&nbsp;&nbsp;HTTPClientSession&nbsp;session(uri.getHost(),&nbsp;uri.getPort());<br />&nbsp;&nbsp;&nbsp;&nbsp;GlobalConfig&nbsp;*&nbsp;gConfig&nbsp;=&nbsp;GlobalConfig::GetInstance();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(gConfig-&gt;proxy().size()&nbsp;&gt;&nbsp;0)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.setProxy(gConfig-&gt;proxy(),&nbsp;gConfig-&gt;proxy_port());<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;std::<span style="color: #0000FF; ">string</span>&nbsp;path(uri.getPathAndQuery());<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>&nbsp;(path.empty())&nbsp;path&nbsp;=&nbsp;"/";<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;"getUrl:path:"&nbsp;&lt;&lt;&nbsp;path&nbsp;&lt;&lt;&nbsp;endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;send&nbsp;request</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;HTTPRequest&nbsp;req(HTTPRequest::HTTP_GET,&nbsp;path,&nbsp;HTTPMessage::HTTP_1_1);<br />&nbsp;&nbsp;&nbsp;&nbsp;session.sendRequest(req);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;HTTPResponse&nbsp;res;<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;res.getStatus()&nbsp;&lt;&lt;&nbsp;"&nbsp;"&nbsp;&lt;&lt;&nbsp;res.getReason()&nbsp;&lt;&lt;&nbsp;endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;print&nbsp;response</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;istream&nbsp;&amp;<span style="color: #0000FF; ">is</span>&nbsp;=&nbsp;session.receiveResponse(res);<br />&nbsp;&nbsp;&nbsp;&nbsp;StreamCopier::copyStream(<span style="color: #0000FF; ">is</span>,&nbsp;cout);<br />}</div><img src ="http://www.cppblog.com/tommy/aggbug/209631.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2015-01-24 22:48 <a href="http://www.cppblog.com/tommy/archive/2015/01/24/209631.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Objective-C 读书笔记</title><link>http://www.cppblog.com/tommy/archive/2013/08/04/202338.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Sun, 04 Aug 2013 13:01:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2013/08/04/202338.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/202338.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2013/08/04/202338.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/202338.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/202338.html</trackback:ping><description><![CDATA[&nbsp; 1. "new" to create an object if no arguments are needed for initialization.<div>&nbsp; &nbsp; e.g. &nbsp; XYZObject *object = [XYZObject new];</div><div></div><div>2. Literals offers a concise object-creation syntax.</div><div>&nbsp; &nbsp; NSString *someString = @"Hello, World !";</div><div></div><div>3. We can create NSNumber using boxed expression, like:</div><div>&nbsp; &nbsp; NSNumber *myInt = @(80/12);</div><div></div><div>4. The "id" type defines a generic object pointer. &nbsp;(object c is a dynamic language! &nbsp;this is just like "var" &nbsp; &nbsp; &nbsp; &nbsp; keyword in C#)</div><div>&nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; id someObject = @"Hello, World!";</div><div></div><div>5. &nbsp;Use "isEqual" to test whether two objects represent the same data, available from NSObject.</div><div>&nbsp; &nbsp; if([firstObject isEqual:secondObject]) ...</div><div></div><div>6. &nbsp;"compare" method is provided by basic Foundation types such as NSNumber, NSString and NSDate.</div><div>&nbsp; &nbsp; if( [someDate compare:anotherDate] == NSOrderedAscending) ...</div><div></div><div>7. It's perfectly acceptable in Object-C to send a message to nil, &nbsp;it's just ignored and return nil for object return type, 0 for numeric types and NO for BOOL types.</div><div></div><div>8. If you want to make sure an object is not null, use this syntax:</div><div>&nbsp; &nbsp; if (somePerson) ... directly, as convenient as Javascript.</div><div></div><div>9. It's important to avoid strong reference cycles.</div><div></div><div>10. Accessor methods are created by compiler:</div><div>&nbsp; &nbsp; &nbsp;NSString *firstName = [somePerson firstName];</div><div>&nbsp; &nbsp; &nbsp;[somePerson setFirstName:@"John"];</div><div></div><div>11. The method used to set the value (the setter method) starts with the word "set" and then uses the capitalized property name.</div><div></div><div>12. "readonly" attribute can be added to a property declaration to specify that it should be readonly, don't want it to be changed via setter method.</div><div>&nbsp; &nbsp; &nbsp; @property (readonly) NSString *fullname;</div><div></div><div>13. Custom name can be specified using attribute on the property:</div><div>&nbsp; &nbsp; &nbsp;@property (getter=isFinished) BOOL finished;</div><div></div><div>14. Simply include the multiple attributes on property as a comma-separated list, like this:</div><div>&nbsp; &nbsp; &nbsp;@property (readonly, getter=isFinished) BOOL finished;</div><div></div><div>15. &nbsp;Dot syntax is a concise alternative to accessor method calls</div><div>&nbsp; &nbsp; &nbsp;NSString *firstName = someperson.firstName;</div><div>&nbsp; &nbsp; &nbsp;somePerson.firstName = @"johnny";</div><div></div><div>16. Should use accessor method or dot syntax for property access even if you're accessing an object's properties from within its own implementation, in such case, should use "self":</div><div>&nbsp; &nbsp; &nbsp; -(void) someMethod {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSString *myString = @"An interesting string";</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.someString = myString;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //or</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [self setSomeString:myString];</div><div>&nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; except when writing initialization, deallocation or custom accessor methods.</div><div></div><div>17. There's a default instance variable created by compiler called _propertyName, &nbsp;we can direct the compiler to synthesize the variable using the following syntax:</div><div>&nbsp; &nbsp; &nbsp;@implementation YourClass</div><div>&nbsp; &nbsp; &nbsp;@synthesize propertyName = instanceVariableName;</div><div>&nbsp; &nbsp; &nbsp;...</div><div>&nbsp; &nbsp; &nbsp;@end</div><div></div><div>18. If using @synthesize without specifying an instance variable name, like this:</div><div>&nbsp; &nbsp; &nbsp;@synthesize firstName;</div><div>&nbsp; &nbsp; &nbsp;the instance variable name will bear the same name as the property. (without underscore as prefix)</div><div></div><div>19. It's best practice to use a property on an object any time you need to keep track of a value or another object.</div><div></div><div>20. If you need to define your own instance variables without declaring a property, add them inside braces at the top of the class interface or implementation, like this:</div><div>&nbsp; &nbsp; &nbsp;@interface SomeClass: NSObject {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSString *_myNonPropertyInstanceVariable; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp;}</div><div></div><div>&nbsp; &nbsp; or</div><div>&nbsp; &nbsp; @implementation SomeClass {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSString *_anotherCustomInstanceVariable;</div><div>&nbsp; &nbsp; }</div><div></div><div>21. Should always access the instance variables directly from within the initialization methods, like:</div><div>&nbsp; &nbsp; - (id) init {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; self = [super init];</div><div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (self) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //initialize instance variables here.</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return self;</div><div>&nbsp; &nbsp; }</div><div></div><div>22. An init method should assign self to the result of calling the superclass's initialization method before doing</div><div>&nbsp; &nbsp; its own initialization. A superclass may fail to initialize the object correctly and return nil. so you should</div><div>&nbsp; &nbsp; always check to make sure self is not nil before performing your own initialization.</div><div></div><div>23. Should decide which method is the designated initializaer. This is often the method that offers the most options</div><div>&nbsp; &nbsp; for initialization (such as the method with the most arguments)</div><div></div><div>24. Should call the superclass's designated initializer (in place of [super init];) before doing any of your own initialization.</div><div></div><div>25. You can implement custom accessor methods which is not backed by their own instance variables. like:</div><div>&nbsp; &nbsp; @property (readonly) NSString *fullname;</div><div>&nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; - (NSString *)fullName {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return [NSString stringWithFormat: @"%@ %@", self.firstName, self.lastName];</div><div>&nbsp; &nbsp; }</div><div></div><div>26. If need to write a custom accessor method for a property that uses an instance variable, must access the vairable directly from within the method.</div><div>&nbsp; &nbsp; like this "lazy initialize method":</div><div>&nbsp; &nbsp; - (XYZObject *)someImportantObject {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if(!_someImportantObject) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _someImportantObject = [[XYZObject alloc] init];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return _someImportantObject;</div><div>&nbsp; &nbsp; }</div><div></div><div>27. The compiler will not synthesize an instance variable automatically if both getter and setter for a readwrite property or a getter for a readonly&nbsp;</div><div>&nbsp; &nbsp; property are implemented by you.</div><div></div><div>28. Properties are atomic by default, the synthesized accessors ensure that a value is always fully retrieved by the getter method or fully set</div><div>&nbsp; &nbsp; via the setter method.</div><div></div><div>29. It's not possible to combine a synthesized accessor with an accessor method that you implement yourself, for example, to provide a custom setter</div><div>&nbsp; &nbsp; for an atomic, readwrite property but leave the compiler to synthesize the getter.</div><div></div><div>30. If property has a "nonatomic" attribute, it's not thread safe, but it's faster to access a nonatomic property, and it's fine to combine a&nbsp;</div><div>&nbsp; &nbsp; synthesized setter, for example, with your own getter implementation.</div><div></div><div>31. Property atomicity is not synonymous with an object's thread safety, thing is more complicated when properties need cooperation.</div><div></div><div>32. When one object relies on other objects and effectively taking ownership of those other objects, the first object is said to have strong references</div><div>&nbsp; &nbsp; to the other objects. an object is kept alive as long as it has at least one strong reference to it from another object.</div><div></div><div>33. If a group of objects is connected by a circle of strong relationships, they keep each other alive even if there are no strong references from&nbsp;</div><div>&nbsp; &nbsp; outside of the group, we should avoid the strong reference cycles.</div><div></div><div>34. One way to break the strong reference cycle is to subsitute one of the strong references for a weak reference.A week reference does not</div><div>&nbsp; &nbsp; imply ownership or responsibility between two objects, and does not keep an object alive. &nbsp;</div><div></div><div>35. To declare a weak reference, add an attribute of (weak) to the property, like this:</div><div>&nbsp; &nbsp; @property (weak) id delegate;</div><div></div><div>36. If you don't want a variable to maintain a strong reference (which is default behaviour), you can declare it as __weak, like this:</div><div>&nbsp; &nbsp; NSObject * __weka weakVariable;</div><div></div><div>37. Weak variables can be a source of confusion, particularly in code like this:</div><div>&nbsp; &nbsp; NSObject * __weak someObject = [[NSObject alloc] init];</div><div>&nbsp; &nbsp; in this example, the newly allocated object has no strong reference to it, so it is immediately deallocated and someObject is set to nil.</div><div></div><div>38. It's important to consider the implications of a method that needs to access a weak property several times, like this:</div><div>&nbsp; &nbsp; - (void) someMethod {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; [self.weakProperty doSomething];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; &nbsp; &nbsp; [self.weakProperty doSomethingElse];</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; in this case, we should cache the weak property in a strong variable to ensure it is kept in memory as long as you need to use it.</div><div>&nbsp; &nbsp; - (void) someMethod {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSObject *cachedObject = self.weakProperty;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; [cachedObject doSomething];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; [cachedObject doSomethingElse];</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp;&nbsp;</div><div>39. It's important to keep in mind if you need to make sure a weak property is not nil before using it, it's not enough just to test it, like this:</div><div>&nbsp; &nbsp; if (self.someWeakProperty) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; [someObject doSomethingImportantWith:self.someWeakProperty];</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; because in a multi-threaded application, the property may be deallocated between the test and the method call, rendering the test useless.</div><div>&nbsp; &nbsp; should to declare a strong local variable to cache the value instead, like this:</div><div>&nbsp; &nbsp; NSObject *cachedObject = self.someWeakProperty; &nbsp; &nbsp; //lock it</div><div>&nbsp; &nbsp; if (cachedObject) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; [someObject doSomethingImportantWith:cachedObject];</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; cachedObject = nil;</div><div></div><div>40. There are some classes in Cocoa and Cocoa Touch that don't yet support weak references, should use unsafe reference instead, like this</div><div>&nbsp; &nbsp; @property (unsafe_unretained) NSObject *unsafeProperty;</div><div>&nbsp; &nbsp; for variables, need to use __unsafe_unretained:</div><div>&nbsp; &nbsp; NSObject * __unsafe_unretained unsafeReference;</div><div>&nbsp; &nbsp; why it's call unsafe is because it won't be set to nil if the destination object is deallocated, so it's dangling.</div><div></div><div>41. The "copy" attribute. used for object to keep its own copy of any objects that are set for its properties.</div><div>&nbsp; &nbsp; example:</div><div>&nbsp; &nbsp; @interface XYZBadgeView: NSView</div><div>&nbsp; &nbsp; @property NSString *firstName;</div><div>&nbsp; &nbsp; @property NSString *lastName;</div><div>&nbsp; &nbsp; @end</div><div>&nbsp; &nbsp; Two NSString properties are declaredd, which both maintain implicit strong references to their objects.</div><div>&nbsp; &nbsp; When another object create a string to set as one of the badge view's properties, like this:</div><div>&nbsp; &nbsp; NSMutableString *nameString = [NSMutableString stringWithString:"John"];</div><div>&nbsp; &nbsp; self.badgeView.firstName = nameString;</div><div>&nbsp; &nbsp; then..</div><div>&nbsp; &nbsp; [nameString appendString:@"ny"];</div><div>&nbsp; &nbsp; the firstName property of badgeView is now "johnny" because the mutable string was changed.</div><div>&nbsp; &nbsp; to avoid such case, add (copy) attribute to the properties, like this:</div><div>&nbsp; &nbsp; @interface XYZBadgeView: NSView</div><div>&nbsp; &nbsp; @property (copy) NSString *firstName;</div><div>&nbsp; &nbsp; @property (copy) NSString *lastName;</div><div>&nbsp; &nbsp; @end &nbsp;</div><div></div><div>42. Any object that wish to set for a copy property must conform to the NSCopying protocol.</div><div>43. If need to set a copy property's instance variable directly, for example in an initializer method,</div><div>&nbsp; &nbsp; don't forget to set a copy of the original object:</div><div>&nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; self = [super init];</div><div>&nbsp; &nbsp; if (self) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; _instanceVariableForCopyProperty = [aString copy];</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; return self;</div><div>&nbsp; &nbsp; ...</div><div></div><div>44. Categories add methods to existing classes:</div><div>&nbsp; &nbsp; @interface ClassName (CategoryName)</div><div>&nbsp; &nbsp; @end</div><div>&nbsp; &nbsp;&nbsp;</div><div>45. At runtime, there's no difference between a method added by a category and one that is implemented by the original class.</div><div>46. A category is usually declared in a separated header file and implemented in a separate source code file.</div><div>47. As well as just adding methods to existing classes, you can also use categories to split the implementation of a complex class</div><div>&nbsp; &nbsp; across multiple source code files.</div><div>48. Categories are not usually suitable for declaring additional properties. it's not possible to declare an additional instance variable in&nbsp;</div><div>&nbsp; &nbsp; a category.</div><div>49. In order to avoid undefined behavior, it's best practice to add a prefix to method names in cateogories on framework classes.</div><div>50. Class extensions extend the internal implementation.</div><div>&nbsp; &nbsp; The methods declared by a class extension are implemented in the @implementation block for the original class.</div><div></div><div>51. The syntax to declare a class extension is similar to category:</div><div>&nbsp; &nbsp; @interface ClassName ()</div><div>&nbsp; &nbsp; @end</div><div>&nbsp; &nbsp; that's why it's also called "anonymous categories"</div><div></div><div>52. Unlike regular categories, a class extension can add its own properties and instance variables to a class.</div><div></div><div>53. Class extensions are often used to extend the public interface with additional private methods or properties for use within the implementation</div><div>&nbsp; &nbsp; of the class itself. for example, to define a property as readonly in the interface, but as readwrite in a class extension declared above</div><div>&nbsp; &nbsp; the implementation, in order that the internal methods of the class can change the property value directly (in implementation file!)</div><div>&nbsp; &nbsp; example:</div><div></div><div>&nbsp; &nbsp; @interface XYZPerson: NSObject</div><div>&nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; @property (readonly) NSString *uniqueIdentifier;</div><div>&nbsp; &nbsp; - (void) assignUniqueIdentifier;</div><div>&nbsp; &nbsp; @end</div><div></div><div>&nbsp; &nbsp; this means it's not possible to change the property from other object directly through the property itself.</div><div>&nbsp; &nbsp; in order for the XYZPersion class to be able to change the property internally, it make sense to redeclare it in a class extension:</div><div>&nbsp; &nbsp; @interface XYZPerson ()</div><div>&nbsp; &nbsp; @property (readwrite) NSString *uniqueIdentifier;</div><div>&nbsp; &nbsp; @end</div><div></div><div>&nbsp; &nbsp; @implementation XYZPerson</div><div>&nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; @end</div><div>&nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; this means that the compiler will now also synthesize a setter method, so any method inside the XYZPerson implementation will be able</div><div>&nbsp; &nbsp; to set the property directly using either the setter or dot syntax.</div><div>&nbsp; &nbsp; and because it's defined in implementation file, it means it's private.</div><div></div><div>54. It's common to have two header files for a class, for example,</div><div>&nbsp; &nbsp; XYZPerson.h and XYZPersonPrivate.h, when you release the framework, only the public XYZPerson.h header file is released.</div><div></div><div>55. Other options for class customization:</div><div>&nbsp; &nbsp; (1) leverage inheritance and leave the decisions in methods specifically designed to be overridden by subclasses.</div><div>&nbsp; &nbsp; (2) use a delegate object, any decision that might limit resusablity can be delegated to another object, which is left to make those&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; decisions at runtime.</div><div>&nbsp; &nbsp; (3) interact directly with the object-c runtime, such as adding "associative references" to an object.</div><div></div><div>56. Protocol, is used to declare methods and properties that are independent of any specific class.</div><div>&nbsp; &nbsp; @protocol ProtocolName</div><div>&nbsp; &nbsp; //list of methods and properties</div><div>&nbsp; &nbsp; @end</div><div></div><div>&nbsp; &nbsp; Protocols can inlcude declarations for both instance methods and class methods, as well as properties.</div><div></div><div>57. Delegate and data source properties are usually marked as weak for object graph management reasons.</div><div></div><div>58. Protocols can have optional methods</div><div>&nbsp; &nbsp; @protocol DataSource</div><div>&nbsp; &nbsp; - (NSUInteger)numberOfSegments;</div><div>&nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; @optional</div><div>&nbsp; &nbsp; - (NSString *)titleForSegmentAtIndex:(NSUInteger)segmentIndex;</div><div>&nbsp; &nbsp; @required</div><div>&nbsp; &nbsp; - ...</div><div>&nbsp; &nbsp; @end</div><div></div><div>59. Check the optional methods are implemented at runtime:</div><div>&nbsp; &nbsp; if( [self.dataSource respondsToSelector:@selector(titleForSegmentAtIndex:)] {</div><div>&nbsp; &nbsp; ...</div><div></div><div>60. Protocols inherit from other protocols:</div><div>&nbsp; &nbsp; @protocol MyProtocol &lt;NSObject&gt;</div><div>&nbsp; &nbsp; ...</div><div></div><div>61. Conforming to protocol:</div><div>&nbsp; &nbsp; @interface MyClass: NSObject &lt;MyProtocol&gt;</div><div>&nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; @end</div><div></div><div>62. Adopt multiple protocols:</div><div>&nbsp; &nbsp; @interface MyClass: NSObject &lt;MyProtocol, AnotherProtocol, YetAnotherProtocol&gt;</div><div>&nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; @end</div><div></div><div>&nbsp; &nbsp; be aware, if there are too many protocols adopted in a class, it's a sign of bad design.</div><div></div><div>63. Some protocols are used to indicate non-hierarchical similarities between classes.</div><div>64. Protocols are also useful in situations where the class of an object isn't known, or needs to stay hidden.</div><div></div><div>65. Some types like NSInteger and NSUInteger, are defined differently depending on the target architecture.</div><div>&nbsp; &nbsp; it's best practice to use these platform-specific types if you might be passing values across API boundaries.</div><div></div><div>66. C structures can hold primitive values.</div><div>67. Strings are represented by instances of the NSString class</div><div>&nbsp; &nbsp; NSString *str = @"Hello, World!";</div><div></div><div>68. The basic NSString class is immutable.</div><div>69. The NSMutableString class is the mutable subclass of NSString.</div><div>70. Numbers of represented by instances of the NSNumber class.</div><div>&nbsp; &nbsp; it's possible to create NSNumber instances using Objective-C literal syntax:</div><div>&nbsp; &nbsp; NSNumber *magicNumber = @42;</div><div>&nbsp; &nbsp; it's possible to request the scalar value using one of the accessor methods:</div><div>&nbsp; &nbsp; int scalarMagic = [magicNumber intValue];</div><div>&nbsp; &nbsp; note: &nbsp;NSNumber is actually a class cluster.</div><div>&nbsp; &nbsp; NSNumber class is itself a subclass of the basic NSValue, NSValue can also be used to represent pointers and structures.</div><div>&nbsp; &nbsp;</div><div>71. @encode compiler directive:</div><div>&nbsp; &nbsp; typedef struct {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int i;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; float f;</div><div>&nbsp; &nbsp; } MyIntegerFloatStruct;</div><div>&nbsp; &nbsp; struct MyIntegerFloatStruct aStruct;</div><div>&nbsp; &nbsp; aStruct.i = 42;</div><div>&nbsp; &nbsp; aStruct.f = 3.14;</div><div>&nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; NSValue *structValue = [NSValue value:&amp;aStruct</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; withObjCType:@encode(MyIntegerFloatStruct)];</div><div></div><div></div><div>72. Most collections are objects.&nbsp;</div><div>&nbsp; &nbsp; collection classes use strong references to keep track of their contents.</div><div></div><div>73. NSArray, NSSet and NSDictionary classes are immutable, each has a mutable subclass to allow you to add or remove objects at will.</div><div></div><div>74. NSArray is used to represent an ordered collection of objects, the only requirement is that each item is an Objective-C object.</div><div></div><div>75. The arrayWithObjects: and initWithObjects: methods both take nil-terminated, variable number of arguments.</div><div>&nbsp; &nbsp; It's possible to truncate the list of items unintentionally if one of the provided values is nil.</div><div></div><div>76. It's possible to create an array using the Objective-C literal like this:</div><div>&nbsp; &nbsp; NSArray *someArray = @[firstObject, secondObject, thirdObject];</div><div>&nbsp; &nbsp; SHOULD NOT terminate the list of objects with nil when using this literal syntax.</div><div>&nbsp; &nbsp; if you do need to represent a nil value in it, should use the NSNull singleton class.</div><div></div><div>77. When try to access item of array using "objectAtIndex" method, should always check the number of items first:</div><div>&nbsp; &nbsp; if([someArray count] &gt; 0) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"First item is: %@", [someArray objectAtIndex:0]);</div><div>&nbsp; &nbsp; }</div><div></div><div>78. NSArray class offers methods to sort its collected objects, because it is immutable, each of these methods returns</div><div>&nbsp; &nbsp; a new array containing the items in the sorted order.</div><div></div><div>79. Usage of NSMutableArray:</div><div>&nbsp; &nbsp; NSMutableArray *mutableArray = [NSMutableArray array];</div><div>&nbsp; &nbsp; [mutableArray addObject: @"gamma"];</div><div>&nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; [mutableArray replaceObjectAtIndex:0 withObject:@"epision"];</div><div></div><div>80. Sort a mutable array in place, without creating a secondary array:</div><div>&nbsp; &nbsp; [mutableArray sortUsingSelector:@selector(caseInsensitiveCompare:)];</div><div></div><div>81. Sets are unordered collections, they don't maintain order, and offer a performance improvement.</div><div></div><div>82. As with NSArray, the iniWithObjects: and setWithObjects: methods of NSSet both take a nil-terminated, variable number of arguments.</div><div>&nbsp; &nbsp; The mutable NSSet subclass is NSMutableSet.</div><div></div><div>83. About NSDictionary, it's best practice to use string objects as dictionary keys.</div><div></div><div>84. Creating dictionaries:</div><div>&nbsp; &nbsp; NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:</div><div>&nbsp; &nbsp; &nbsp; &nbsp; someObject, @"anObject",</div><div>&nbsp; &nbsp; &nbsp; &nbsp; @"Hello, World!", @"hellowString",</div><div>&nbsp; &nbsp; &nbsp; &nbsp; @42, @"magicNumber",</div><div>&nbsp; &nbsp; &nbsp; &nbsp; someValue, @"aValue",</div><div>&nbsp; &nbsp; &nbsp; &nbsp; nil];</div><div></div><div>&nbsp; &nbsp; each object is specified before its key, and the list of objects and keys must be nil-terminated.</div><div></div><div>objectAtIndex" method, should always check the number of items first:</div><div>&nbsp; &nbsp; if([someArray count] &gt; 0) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"First item is: %@", [someArray objectAtIndex:0]);</div><div>&nbsp; &nbsp; }</div><div></div><div>85. Like NSArray, NSDictionary also can be created in a literal form:</div><div>&nbsp; &nbsp; NSDictionary *dictionary = @{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; @"anObject": someObject,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; @"helloString": @"Hello, World!",</div><div>&nbsp; &nbsp; &nbsp; &nbsp; @magicNumber": @42,</div><div>&nbsp; &nbsp; &nbsp; &nbsp; @"aValue": someValue</div><div>&nbsp; &nbsp; };</div><div>&nbsp; &nbsp; and with out nil-terminated, &nbsp;the structure is just like Javascript object definition.</div><div></div><div>86. Query dictionary:</div><div>&nbsp; &nbsp; NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"];</div><div>&nbsp; &nbsp; if the object isn't found, nil will be returned.</div><div>&nbsp; &nbsp; we can also use subscript syntax alternative like this:</div><div>&nbsp; &nbsp; NSNumber *storedNumber = dictionary[@"magicNumber"];</div><div></div><div>87. Mutable version: &nbsp;NSMutableDictionary</div><div>&nbsp; &nbsp; [dictionary setObject:@another string" forKey:@"secondString"];</div><div>&nbsp; &nbsp; [dictionary removeObjectForKey:@"anObject"];</div><div></div><div>88.Representing nil with NSNull</div><div>&nbsp; &nbsp; NSArray *array = @[@"string", @42, [NSNull null]];</div><div></div><div>89. The NSArray and NSDictionary classes make it easy to write their contents directly to disk like this:</div><div>&nbsp; &nbsp; NSURL *fileURL = ...</div><div>&nbsp; &nbsp; NSArray *array = @[@"first", @"second", @"third"];</div><div>&nbsp; &nbsp; BOOL success = [array writeToURL:fileURL atomically:YES];</div><div>&nbsp; &nbsp; if(!success) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //an error occured</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; if every contained object is one of the property list types( NSArray, NSDictionary, NSString, NSData, NSDate and NSNumber),</div><div>&nbsp; &nbsp; it's easy to recreate the entire hierarchy from disk:</div><div>&nbsp; &nbsp; NSURL *fileURL = ...</div><div>&nbsp; &nbsp; NSArray *array = [NSArray arrayWithContentsOfURL:fileURL];</div><div>&nbsp; &nbsp; if(!array) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //an error occured</div><div>&nbsp; &nbsp; }</div><div></div><div>90. If need to persist other types of objects, we can use an archiver object such as NSKeyedArchiver, the only requirement to&nbsp;</div><div>&nbsp; &nbsp; create an archive is that each object must support the NSCoding protocol.</div><div></div><div>91. Many collection classes conform to the NSFastEnumeration protocol, including NSArray, NSSet and NSDictionary, syntax:</div><div>&nbsp; &nbsp; for (&lt;type&gt; &lt;variable&gt; in &lt;colleciton&gt;) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; }</div><div></div><div>92. If you use fast enumeration with a dictionary, you iterate over the dictionary keys like this:</div><div>&nbsp; &nbsp; for( NSString *eachKey in dictionary) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; id object = dictionary[eachKey];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"Object: %@ for key: %@", object,eachKey);</div><div>&nbsp; &nbsp; }</div><div></div><div>93. You cannot mutate a collection during fast enumeration.</div><div></div><div>94. It's also possible to enumeratemany Coca and Cocoa Touch collections by using an NSEnumerator object.</div><div>&nbsp; &nbsp; for (id eachObject in [array reverseObjectEnumerator]) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; }</div><div></div><div>95. It's also possible to iterate through the contents by calling the enumerator's nextObject method repeatedly like this:</div><div>&nbsp; &nbsp; id eachObject;</div><div>&nbsp; &nbsp; while ( (eachObject = [enumerator nextObject]) ) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"Current object is: %@", eachObject);</div><div>&nbsp; &nbsp; }</div><div></div><div>96. Because it's a common programmer error to use the C assignment operator (=) when you mean the quality test operator (==),&nbsp;</div><div>&nbsp; &nbsp; the compiler will warn you if you set a variable in a conditional branch or loop, like this:</div><div>&nbsp; &nbsp; if (someVariable = YES) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; if you really want to do this, &nbsp;indicate this by placing the assignment in parentheses like this:</div><div>&nbsp; &nbsp; if ( (someVariable = YES ) ) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; }</div><div></div><div>97. Many collections support block-based enumeration.</div><div></div><div>98. Blocks are like closures or lambdas in other programming language.</div><div></div><div>99. Syntax of blocks:</div><div>&nbsp; &nbsp; ^{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"This is a block");</div><div>&nbsp; &nbsp; }</div><div></div><div>100.You can declare a variable to keep track of a block, like this:</div><div>&nbsp; &nbsp; void (^simpleBlock)(void);</div><div>&nbsp; &nbsp; the same syntax as function pointers:)</div><div></div><div>101.Block can operate just like a method, can have arguments and return value:</div><div>&nbsp; &nbsp; ^ double (double firstValue, double secondValue) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return firstValue * secondValue;</div><div>&nbsp; &nbsp; }</div><div></div><div>102.Blocks can capture values from the enclosing scope</div><div>&nbsp; &nbsp; - (void)testMethod {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; int anInteger = 42;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; void (^testBlock)(void) = ^{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"Integer is: %i", anInteger);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; };</div><div>&nbsp; &nbsp; &nbsp; &nbsp; testBlock();</div><div>&nbsp; &nbsp; }</div><div></div><div>103.The block cannot change the value of the original variable, or even the captured value (it's captured as a const variable)</div><div></div><div>104.Use __block variables to share storage:</div><div>&nbsp; &nbsp; if you need to be able to change the value of a captured variable from within a block, use __block storage type modifier on the original</div><div>&nbsp; &nbsp; variable declaration like this:</div><div>&nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; __block int anInteger = 42;</div><div>&nbsp; &nbsp; void (^testBlock)(void) = ^{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"Integer is: %i", anInteger);</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; anInteger = 84;</div><div>&nbsp; &nbsp; testBlock();</div><div></div><div>105.You can pass blocks as arguments to methods or functions, an simplify some tasks:</div><div>&nbsp; &nbsp;- (IBAction)fetchRemoteInformation:(id)sender {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; [self showProgressIndicator];</div><div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; XYZWebTask *task = ...</div><div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; [task beginTaskWithCallbackBlock:^{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [self hideProgressIndicator];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }];</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; It's important to take care when capturing "self" because it's easy to create strong reference cycle.</div><div></div><div>106.A block should always be the last argument to a method.</div><div></div><div>107.We can use type definition to simplify block syntax, like this:</div><div>&nbsp; &nbsp; typedef void (^XYZSimpleBlock)(void);</div><div></div><div>108.We can use properties to keep track of blocks, like this:</div><div>&nbsp; &nbsp; @interface XYZObject: NSObject</div><div>&nbsp; &nbsp; @property (copy) void (^blockProperty)(void);</div><div>&nbsp; &nbsp; @end</div><div></div><div>109.It's possible to use type definition for block property declarations, like this:</div><div>&nbsp; &nbsp; typedef void (^XYZSimpleBlock)(void);</div><div>&nbsp; &nbsp;&nbsp;</div><div>&nbsp; &nbsp; @interface XYZObject: NSObject</div><div>&nbsp; &nbsp; @property (copy) XYZSimpleBlock blockProperty;</div><div>&nbsp; &nbsp; @end</div><div></div><div>110.To avoid strong reference when capturing "self" in block, should use weak reference like this:</div><div>&nbsp; &nbsp; - (void)configureBlock {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; XYZBlockKeeper * __weak weakSelf = self;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; self.block = ^{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [weakSelf doSomething];</div><div></div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; }</div><div></div><div>111.Blocks can simplify iteration:</div><div>&nbsp; &nbsp; NSArray *array = ...</div><div>&nbsp; &nbsp; [array enumerateObjectsUsingBlock:^ (id obj, NSUInteger idx, BOOL *stop) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"Object at index %lu is %@", idx, obj);</div><div>&nbsp; &nbsp; }];</div><div></div><div>112.If the code in the enumeration block is process-intensive--and safe for concurrent execution-- can use this:</div><div>&nbsp; &nbsp; [array enumerateObjectsWithOptions:NSEnumerationConcurrent</div><div>&nbsp; &nbsp; &nbsp; &nbsp; usingBlock:^ (id obj, NSUInteger idx, BOOL *stop) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; }];</div><div></div><div>113.Block based method in NSDictionary:</div><div>&nbsp; &nbsp; NSDictionary *dictionary = ...</div><div>&nbsp; &nbsp; [dictionary enumerateKeysAndObjectsUsingBlock:^ (id key, id obj, BOOL *stop) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"key:%@, value: %@", key, obj);</div><div>&nbsp; &nbsp; }];</div><div></div><div>114.Blocks can simplify concurrent tasks, you can create NSOperation instance to encapsulate a unit of work along with</div><div>&nbsp; &nbsp; any neccessary data, the add that operation to an NSOperationQueue for execution.</div><div>&nbsp; &nbsp; although you can create your own custom NSOperation subclass to implement complex tasks, it's also possible to use</div><div>&nbsp; &nbsp; the NSBlockOperation to create an operation using a block, like this:</div><div>&nbsp; &nbsp; NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ..</div><div>&nbsp; &nbsp; }];</div><div></div><div></div><div>115.Queue:</div><div>&nbsp; &nbsp; //schedule task on main queue:</div><div>&nbsp; &nbsp; NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];</div><div>&nbsp; &nbsp; [mainQueue addOperation:operation];</div><div>&nbsp; &nbsp; //schedule task on background queue:</div><div>&nbsp; &nbsp; NSOperationQueue *queue = [[NSOperationQueue alloc] init];</div><div>&nbsp; &nbsp; [queue addOperation:operation];</div><div></div><div>116.Schedule blocks on dispatch queues with Grand Central Dispatch:</div><div>&nbsp; &nbsp; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);</div><div>&nbsp; &nbsp; dispatch_async(queue, ^{</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"Block for asynchronous execution");</div><div>&nbsp; &nbsp; });</div><div></div><div>117.Only programming error using exception, all other errors are represented by instances of the NSError class.</div><div>&nbsp; &nbsp; - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;</div><div>&nbsp; &nbsp; rather than making the requirement that every possible error have a unique numeric code, Cocoa and CocoaTouch&nbsp;</div><div>&nbsp; &nbsp; errors are divided into domains.</div><div>&nbsp; &nbsp; example, the connection:didFailWithError: method above will privide an error from NSURLErrorDomain.</div><div>&nbsp; &nbsp; the error object also incudes a localized description.</div><div></div><div>118.Some Methods pass errors by reference:</div><div>&nbsp; &nbsp; - (BOOL)writeToURL:(NSURL *)aURL</div><div>&nbsp; &nbsp; &nbsp; &nbsp; options:(NSDataWritingOptions)mask</div><div>&nbsp; &nbsp; &nbsp; &nbsp; error:(NSError **)errorPtr;</div><div></div><div>&nbsp; &nbsp; //invoke</div><div>&nbsp; &nbsp; NSError *anyError;</div><div>&nbsp; &nbsp; BOOL success = [receivedData writeToURL:someLocalFileURL</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; options:0</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; error:&amp;anyError];</div><div>&nbsp; &nbsp; if(!success) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@"Write failed with error: %@", anyError);</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //present errors to user</div><div>&nbsp; &nbsp; }</div><div></div><div>119.It's important to test the return value of the method to see whether an error occured, don't just test whether the</div><div>&nbsp; &nbsp; error pointer was set to point to an error, it's not reliable.</div><div></div><div>120.Create your own errors:</div><div>&nbsp; &nbsp; first you need to define your own error domain, like this:</div><div>&nbsp; &nbsp; com.companyName.appOrFrameworkname.ErrorDomain</div><div>&nbsp; &nbsp; you'll also need to pick a unique error code for each error that may occur in your domain, along with a suitable</div><div>&nbsp; &nbsp; description, which is stored in the user info dictionary for the error, like this:</div><div>&nbsp; &nbsp; NSString *domain = @"com.MyCompany.MyApplication.ErrorDomain";</div><div>&nbsp; &nbsp; NSString *desc = NSLocalizedString(@"Unable to...", @"");</div><div>&nbsp; &nbsp; NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: desc };</div><div>&nbsp; &nbsp; NSError *error = [NSError errorWithDomain:domain</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; code:-101</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userInfo:userInfo];</div><div></div><div>121.If you need to pass back an error by reference as describe above your method signature should include a parameter for</div><div>&nbsp; &nbsp; a pointer to a pointer to an NSError object. should also use the return value to indicate success or failure, like this:</div><div>&nbsp; &nbsp; - (BOOL)doSomethingThatMayGenerateAnError:(NSError **)errorPtr {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; ...</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //error occured</div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (errorPtr) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *errorPtr = [NSError errorWithDomain:...</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; code:...</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; userInfo:...];</div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div><div>&nbsp; &nbsp; &nbsp; &nbsp; return NO;</div><div>&nbsp; &nbsp; }</div><div></div><div>122.Exceptions are used for programming errors:</div><div>&nbsp; &nbsp; @try {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //do something that might throw an exception</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; @catch (NSException *exception) {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //deal with the exception</div><div>&nbsp; &nbsp; }</div><div>&nbsp; &nbsp; @finally {</div><div>&nbsp; &nbsp; &nbsp; &nbsp; //optional block of clean-up code</div><div>&nbsp; &nbsp; }</div><div></div><div>123.Some naming conventions:</div><div>&nbsp; &nbsp; NS -- Foundation (OSX and iOS) and Application Kit(OSX)</div><div>&nbsp; &nbsp; UI -- UIKit (iOS)</div><div>&nbsp; &nbsp; AB -- Address Book</div><div>&nbsp; &nbsp; CA -- Core Animation</div><div>&nbsp; &nbsp; CI -- Core Image</div><div></div><div>124.Method names do not have a prefix, and should start with a lowercase letter; camel case is used again for multiple words.</div><div></div><div>125.If a method includes an error pointer parameter to be set if an error occurred, this should be the last parameter to the method.</div><div></div><div>126.Accessor method names must follow conventions, the compiler automatically synthesizes the relevant getter and setter methods,</div><div>&nbsp; &nbsp; a getter method should use the same name as property, the exception to this rule is for Boolean properties, for which the getter</div><div>&nbsp; &nbsp; method should start with is.</div><div></div><div>127.the setter method for a property should use the form setPropertyname:</div><div></div><div>128.Althoug the @property syntax allows you to specify different accessor method names, you should only do so for situations like</div><div>&nbsp; &nbsp; a Boolean property. It's essential to follow the conventions described here, otherwise technques like Key Value Coding won't work.</div><div></div><div>129.Class factory methods should always start with the name of the class (without the prefix) that they create, with the exception</div><div>&nbsp; &nbsp; of subclasses of classes with existing factory methods. for example, NSArray, the factory methods start with array.</div><div>&nbsp; &nbsp; the NSMutableArray class doesn't define any of its own class-specific factory methods, so the factory methods for a mutable array&nbsp;</div><div>&nbsp; &nbsp; still begin with array.</div><div></div><img src ="http://www.cppblog.com/tommy/aggbug/202338.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2013-08-04 21:01 <a href="http://www.cppblog.com/tommy/archive/2013/08/04/202338.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vs2012 编译 Qt5.0</title><link>http://www.cppblog.com/tommy/archive/2013/01/19/197410.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Sat, 19 Jan 2013 05:23:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2013/01/19/197410.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/197410.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2013/01/19/197410.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/197410.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/197410.html</trackback:ping><description><![CDATA[资料转自网络:<br /><div>原文在此： http://www.qtcn.org/bbs/simple/?t52158.html</div><br /><span style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;">1 &nbsp;</span><span style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;">安装vs2012 update1</span><br style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;" /><br style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;" /><span style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;">2 &nbsp;下载qt5源码包，记住，windows下要下载zip结尾的，不要看到tar.gz的小就下它，tar.gz的源码包不能直接在windows下编译</span><br style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;" /><br style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;" /><span style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;">编译</span><br style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;" /><br style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;" /><span style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;">1) 我要编译x86， 所以打开vc x86命令提示符，其他版尚未成功</span><br style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;" /><br /><span style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;">2) cd &lt;path&gt;\qt-everywhere-opensource-src-&lt;version&gt;</span><span style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;"><br />&nbsp;&nbsp; configure -prefix %CD%\qtbase -opensource -nomake tests -nomake examples -mp</span><br style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;" /><span style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;">&nbsp;&nbsp; 如果想编译例子，可以去掉-nomake examples<br /></span><br style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;" /><span style="font-family: Verdana; font-size: 13.142857551574707px; line-height: normal; background-color: #ffffff;">3) 执行nmake 开始编译。</span><img src ="http://www.cppblog.com/tommy/aggbug/197410.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2013-01-19 13:23 <a href="http://www.cppblog.com/tommy/archive/2013/01/19/197410.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BGL学习</title><link>http://www.cppblog.com/tommy/archive/2012/12/29/196797.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Sat, 29 Dec 2012 12:17:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2012/12/29/196797.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/196797.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2012/12/29/196797.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/196797.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/196797.html</trackback:ping><description><![CDATA[摘自 《The Boost Graph Library》<br />
代码示例在 vc2012下编译通过。<br />
<br />
图类与适配器<br />
<br />
1.类<br />
<br />
adjacency_list 用于稀疏图，用例如下：<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
-->#include&nbsp;&lt;iostream&gt;<br />
#include&nbsp;&lt;vector&gt;<br />
#include&nbsp;&lt;<span style="color: #0000FF; ">string</span>&gt;<br />
#include&nbsp;&lt;boost/graph/adjacency_list.hpp&gt;<br />
#include&nbsp;&lt;boost/tuple/tuple.hpp&gt;<br />
<br />
<span style="color: #0000FF; ">enum</span>&nbsp;family&nbsp;{&nbsp;Jeanie,&nbsp;Debbie,&nbsp;Rick,&nbsp;John,&nbsp;Amanda,&nbsp;Margaret,&nbsp;Benjamin,&nbsp;N&nbsp;};<br />
<br />
<span style="color: #0000FF; ">int</span>&nbsp;main()<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;boost;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*name[]&nbsp;=&nbsp;{"Jeanie",&nbsp;"Debbie",&nbsp;"Rick",&nbsp;"John",&nbsp;"Amanda",&nbsp;"Margaret",&nbsp;"Benjamin"};<br />
&nbsp;&nbsp;&nbsp;&nbsp;adjacency_list&lt;&gt;&nbsp;g(N);<br />
&nbsp;&nbsp;&nbsp;&nbsp;add_edge(Jeanie,Debbie,g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;add_edge(Jeanie,Rick,g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;add_edge(Jeanie,John,g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;add_edge(Debbie,Amanda,g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;add_edge(Rick,Margaret,g);<br />
&nbsp;&nbsp;&nbsp;&nbsp;add_edge(John,Benjamin,g);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;graph_traits&lt;adjacency_list&lt;&gt;&nbsp;&gt;::vertex_iterator&nbsp;i,end;<br />
&nbsp;&nbsp;&nbsp;&nbsp;graph_traits&lt;adjacency_list&lt;&gt;&nbsp;&gt;::adjacency_iterator&nbsp;ai,a_end;<br />
&nbsp;&nbsp;&nbsp;&nbsp;property_map&lt;adjacency_list&lt;&gt;,vertex_index_t&gt;::type&nbsp;index_map&nbsp;=&nbsp;<span style="color: #0000FF; ">get</span>(vertex_index,g);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(tie(i,end)&nbsp;=&nbsp;vertices(g);&nbsp;i&nbsp;!=&nbsp;end;&nbsp;++i)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;name[<span style="color: #0000FF; ">get</span>(index_map,*i)];<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; boost::<span style="color: #008000; ">tie(ai,a_end)&nbsp;=</span>&nbsp;adjacent_vertices(*i,&nbsp;g);<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(ai&nbsp;==&nbsp;a_end)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"&nbsp;has&nbsp;no&nbsp;children.";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">else</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;"&nbsp;is&nbsp;the&nbsp;parent&nbsp;of&nbsp;";&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(;&nbsp;ai&nbsp;!=&nbsp;a_end;&nbsp;++ai)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;name[<span style="color: #0000FF; ">get</span>(index_map,&nbsp;*ai)];<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">if</span>(boost::next(ai)&nbsp;!=&nbsp;a_end)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;",&nbsp;";<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;std::endl;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;EXIT_SUCCESS;<br />
} &nbsp;</div><br /><br />2. 拓扑排序算法<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->#include&nbsp;&lt;deque&gt;<br />#include&nbsp;&lt;vector&gt;<br />#include&nbsp;&lt;list&gt;<br />#include&nbsp;&lt;iostream&gt;<br />#include&nbsp;&lt;boost/graph/vector_as_graph.hpp&gt;<br />#include&nbsp;&lt;boost/graph/topological_sort.hpp&gt;<br />#include&nbsp;&lt;boost/graph/adjacency_list.hpp&gt;<br /><br /><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;boost;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;*tasks[]&nbsp;=&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"pick&nbsp;up&nbsp;kids&nbsp;from&nbsp;school",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"buy&nbsp;groceries&nbsp;snacks",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"get&nbsp;cash&nbsp;at&nbsp;ATM",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"drop&nbsp;off&nbsp;kids&nbsp;at&nbsp;soccer&nbsp;practice",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"cook&nbsp;dinner",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"pick&nbsp;up&nbsp;kids&nbsp;from&nbsp;soccer",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"eat&nbsp;dinner",<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"before&nbsp;drop&nbsp;off"<br />&nbsp;&nbsp;&nbsp;&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">const</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;n_tasks&nbsp;=&nbsp;<span style="color: #0000FF; ">sizeof</span>(tasks)&nbsp;/&nbsp;<span style="color: #0000FF; ">sizeof</span>(<span style="color: #0000FF; ">char</span>*);<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; "><br />&nbsp;&nbsp;&nbsp;&nbsp;std::vector&lt;std::list&lt;int&gt;&nbsp;&gt;&nbsp;g(n_tasks);<br />&nbsp;&nbsp;&nbsp;&nbsp;g[0].push_back(3);<br />&nbsp;&nbsp;&nbsp;&nbsp;g[1].push_back(3);<br />&nbsp;&nbsp;&nbsp;&nbsp;g[1].push_back(4);<br />&nbsp;&nbsp;&nbsp;&nbsp;g[2].push_back(1);<br />&nbsp;&nbsp;&nbsp;&nbsp;g[3].push_back(5);<br />&nbsp;&nbsp;&nbsp;&nbsp;g[4].push_back(6);<br />&nbsp;&nbsp;&nbsp;&nbsp;g[5].push_back(6);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;adjacency_list&lt;listS,vecS,directedS&gt;&nbsp;g(n_tasks);<br />&nbsp;&nbsp;&nbsp;&nbsp;add_edge(7,3,g);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;add_edge(0,3,g);<br />&nbsp;&nbsp;&nbsp;&nbsp;add_edge(1,3,g);<br />&nbsp;&nbsp;&nbsp;&nbsp;add_edge(1,4,g);<br />&nbsp;&nbsp;&nbsp;&nbsp;add_edge(2,1,g);<br />&nbsp;&nbsp;&nbsp;&nbsp;add_edge(3,5,g);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;add_edge(5,6,g);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;add_edge(4,6,g);<br />&nbsp;&nbsp;&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">perform&nbsp;the&nbsp;topological&nbsp;sort&nbsp;and&nbsp;output&nbsp;the&nbsp;result</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;std::deque&lt;<span style="color: #0000FF; ">int</span>&gt;&nbsp;topo_order;<br />&nbsp;&nbsp;&nbsp;&nbsp;topological_sort(g,&nbsp;std::front_inserter(topo_order),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vertex_index_map(identity_property_map()));<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;n&nbsp;=&nbsp;1;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">for</span>(std::deque&lt;<span style="color: #0000FF; ">int</span>&gt;::iterator&nbsp;i=topo_order.begin();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i&nbsp;!=&nbsp;topo_order.end();&nbsp;++i,&nbsp;++n)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::cout&nbsp;&lt;&lt;&nbsp;tasks[*i]&nbsp;&lt;&lt;&nbsp;std::endl;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;EXIT_SUCCESS;<br />}</div><br />今天还学习了 BCCL 库，即 &nbsp;Boost concept check library, 检查模型是否满足模板要求并提供较精准的编译错误信息。<br /><br />关于如何存取BGL的算法: 应加boost前缀，如 boost:breadth_first_search<br /><br /><img src ="http://www.cppblog.com/tommy/aggbug/196797.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2012-12-29 20:17 <a href="http://www.cppblog.com/tommy/archive/2012/12/29/196797.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>py2exe - No module named Alchemy problem resolved</title><link>http://www.cppblog.com/tommy/archive/2012/05/24/176016.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Thu, 24 May 2012 07:16:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2012/05/24/176016.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/176016.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2012/05/24/176016.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/176016.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/176016.html</trackback:ping><description><![CDATA[I need to package PyQt program to windows executable file, there's Alchemy library used.<br />when "setup.py" file prepared and run, "No module named Alchemy" encountered.<br /><br />so trace to mf.py file, py2exe just parse the lib directory to find modules, so I checked python27 folder,<br />in the lib directory, there's no sqlalchemy found, so i decide to download the sources of sqlalchemy,<br />check the site and several steps needed:<br /><br />1. download Mercurial and install it.<br />2. use Mercurial to clone sqlalchemy's source<br />3. copy the module source folder (with __init__.py inside) to python27/lib/, like this: c:\python27\lib\sqlalchemy<br /><br />now run setup.py again, problem resolved.<img src ="http://www.cppblog.com/tommy/aggbug/176016.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2012-05-24 15:16 <a href="http://www.cppblog.com/tommy/archive/2012/05/24/176016.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python 读书笔记</title><link>http://www.cppblog.com/tommy/archive/2012/04/19/171926.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Wed, 18 Apr 2012 18:09:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2012/04/19/171926.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/171926.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2012/04/19/171926.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/171926.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/171926.html</trackback:ping><description><![CDATA[Syntax best practice:<br />
<ul>
     <li>
     <div>List Comprehensions<br />
     <div><span style="background-color: #eeeeee; font-size: 13px; ">&gt;&gt;&gt;</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;[i&nbsp;</span><span style="background-color: #eeeeee; font-size: 13px; color: #0000ff; ">for</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;i&nbsp;</span><span style="background-color: #eeeeee; font-size: 13px; color: #0000ff; ">in</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;range(</span><span style="background-color: #eeeeee; font-size: 13px; ">10</span><span style="background-color: #eeeeee; font-size: 13px; ">)&nbsp;</span><span style="background-color: #eeeeee; font-size: 13px; color: #0000ff; ">if</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;i&nbsp;</span><span style="background-color: #eeeeee; font-size: 13px; ">%</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;</span><span style="background-color: #eeeeee; font-size: 13px; ">2</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;</span><span style="background-color: #eeeeee; font-size: 13px; ">==</span><span style="background-color: #eeeeee; font-size: 13px; ">&nbsp;0]</span><br />
     <br />Enumeration:<br />
     <div>
     <div style="font-size: 13px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: #cccccc; border-right-color: #cccccc; border-bottom-color: #cccccc; border-left-color: #cccccc; border-image: initial; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; padding-top: 4px; width: 98%; word-break: break-all; background-color: #eeeeee; "><!--<br />
     <br />
     Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
     http://www.CodeHighlighter.com/<br />
     <br />
     -->&gt;&gt;&gt;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;_treatment(pos,&nbsp;element):<br />
     <img src="http://www.cppblog.com/Images/dot.gif" alt="" />&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">%d:&nbsp;%s</span><span style="color: #800000; ">'</span>&nbsp;%&nbsp;(pos,&nbsp;element)<br />
     <img src="http://www.cppblog.com/Images/dot.gif" alt="" /><br />
     &gt;&gt;&gt;&nbsp;seq&nbsp;=&nbsp;[<span style="color: #800000; ">"</span><span style="color: #800000; ">one</span><span style="color: #800000; ">"</span>,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">two</span><span style="color: #800000; ">"</span>,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">three</span><span style="color: #800000; ">"</span>]<br />
     &gt;&gt;&gt;&nbsp;[_treatment(i,&nbsp;el)&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;i,&nbsp;el&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;enumerate(seq)]<br />
     [<span style="color: #800000; ">'</span><span style="color: #800000; ">0:&nbsp;one</span><span style="color: #800000; ">'</span>,&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">1:&nbsp;two</span><span style="color: #800000; ">'</span>,&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">2:&nbsp;three</span><span style="color: #800000; ">'</span>]</div><div><br />Iterators and Generators<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&gt;&gt;&gt;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;fibonacci():<br /><img src="http://www.cppblog.com/Images/dot.gif" alt="" />&nbsp;a,&nbsp;b&nbsp;=&nbsp;0,&nbsp;1<br /><img src="http://www.cppblog.com/Images/dot.gif" alt="" />&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;True:<br /><img src="http://www.cppblog.com/Images/dot.gif" alt="" />&nbsp;<span style="color: #0000FF; ">yield</span>&nbsp;b &nbsp;# 这里返回 generator，一个特殊的iterator<br /><img src="http://www.cppblog.com/Images/dot.gif" alt="" />&nbsp;a,&nbsp;b&nbsp;=&nbsp;b,&nbsp;a&nbsp;+&nbsp;b<br /><img src="http://www.cppblog.com/Images/dot.gif" alt="" /><br />&gt;&gt;&gt;&nbsp;fib&nbsp;=&nbsp;fibonacci()<br />&gt;&gt;&gt;&nbsp;fib.next()<br />1<br />&gt;&gt;&gt;&nbsp;fib.next()<br />1<br />&gt;&gt;&gt;&nbsp;fib.next()<br />2<br />&gt;&gt;&gt;&nbsp;[fib.next()&nbsp;<span style="color: #0000FF; ">for</span>&nbsp;i&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;range(10)]<br />[3,&nbsp;5,&nbsp;8,&nbsp;13,&nbsp;21,&nbsp;34,&nbsp;55,&nbsp;89,&nbsp;144,&nbsp;233]</div></div><div><strong>generators should be considered every time you deal with a</strong></div><div><strong>function that returns a sequence or works in a loop;<br /><div>It is better to have a lot of simple iterable functions that work over</div><div>sequences of values than a complex function that computes the result for</div><div>one value at a time.</div></strong></div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->&gt;&gt;&gt;&nbsp;<span style="color: #0000FF; ">def</span>&nbsp;my_generator():<br /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;<span style="color: #0000FF; ">try</span>:<br /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;<span style="color: #0000FF; ">yield</span>&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">something</span><span style="color: #800000; ">'</span><br /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;<span style="color: #0000FF; ">except</span>&nbsp;ValueError:<br /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;<span style="color: #0000FF; ">yield</span>&nbsp;<span style="color: #800000; ">'</span><span style="color: #800000; ">dealing&nbsp;with&nbsp;the&nbsp;exception</span><span style="color: #800000; ">'</span><br /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;<span style="color: #0000FF; ">finally</span>:<br /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" />&nbsp;<span style="color: #0000FF; ">print</span>&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">ok&nbsp;let's&nbsp;clean</span><span style="color: #800000; ">"</span><br /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /><br />&gt;&gt;&gt;&nbsp;gen&nbsp;=&nbsp;my_generator()<br />&gt;&gt;&gt;&nbsp;gen.next()<br /><span style="color: #800000; ">'</span><span style="color: #800000; ">something</span><span style="color: #800000; ">'</span><br />&gt;&gt;&gt;&nbsp;gen.throw(ValueError(<span style="color: #800000; ">'</span><span style="color: #800000; ">mean&nbsp;mean&nbsp;mean</span><span style="color: #800000; ">'</span>))<br /><span style="color: #800000; ">'</span><span style="color: #800000; ">dealing&nbsp;with&nbsp;the&nbsp;exception</span><span style="color: #800000; ">'</span><br />&gt;&gt;&gt;&nbsp;gen.close()<br />ok&nbsp;let<span style="color: #800000; ">'</span><span style="color: #800000; ">s&nbsp;clean</span><span style="color: #800000; "><br /></span>&gt;&gt;&gt;&nbsp;gen.next()<br />Traceback&nbsp;(most&nbsp;recent&nbsp;call&nbsp;last):<br />File&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">&lt;stdin&gt;</span><span style="color: #800000; ">"</span>,&nbsp;line&nbsp;1,&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;&lt;module&gt;<br />StopIteration</div><hr />
     </div>
     </div>
     </div>
     </li>
</ul><img src ="http://www.cppblog.com/tommy/aggbug/171926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2012-04-19 02:09 <a href="http://www.cppblog.com/tommy/archive/2012/04/19/171926.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>找到介绍UI逻辑管理的系列文章</title><link>http://www.cppblog.com/tommy/archive/2012/03/23/168721.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Fri, 23 Mar 2012 06:51:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2012/03/23/168721.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/168721.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2012/03/23/168721.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/168721.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/168721.html</trackback:ping><description><![CDATA[<a href="http://codebetter.com/jeremymiller/2007/07/06/build-your-own-cab-13-embedded-controllers-with-a-dash-of-dsl/">http://codebetter.com/jeremymiller/2007/07/06/build-your-own-cab-13-embedded-controllers-with-a-dash-of-dsl/</a>&nbsp;<img src ="http://www.cppblog.com/tommy/aggbug/168721.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2012-03-23 14:51 <a href="http://www.cppblog.com/tommy/archive/2012/03/23/168721.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>javascript float problem</title><link>http://www.cppblog.com/tommy/archive/2011/11/22/160723.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Tue, 22 Nov 2011 10:16:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2011/11/22/160723.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/160723.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2011/11/22/160723.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/160723.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/160723.html</trackback:ping><description><![CDATA[<div><div>&lt;script language=javascript&gt;</div><div><span style="white-space:pre">		</span>function ceil(number,significance){</div><div><span style="white-space:pre">			</span>if(significance){</div><div><span style="white-space:pre">				</span>return Math.ceil(number/significance) * significance;</div><div><span style="white-space:pre">			</span>}</div><div><span style="white-space:pre">			</span>return Math.ceil(number);</div><div><span style="white-space:pre">		</span>}</div><div><span style="white-space:pre">		</span>document.write(ceil((2025.4/(2000+2*19.05-12.7)).toFixed(3),1));</div><div><span style="white-space:pre">		</span>document.write("&lt;br/&gt;");</div><div><span style="white-space:pre">		</span>document.write(ceil(2.98,2));</div><div><span style="white-space:pre">	</span>&lt;/script&gt;<br /><br />note: &nbsp;ceil((2025.4/(2000+2*19.05-12.7)),1) = 2, because of float problem, toFixed(prec) fix the problem.</div></div><img src ="http://www.cppblog.com/tommy/aggbug/160723.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2011-11-22 18:16 <a href="http://www.cppblog.com/tommy/archive/2011/11/22/160723.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ubuntu efficiency adjustment</title><link>http://www.cppblog.com/tommy/archive/2011/11/11/159944.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Thu, 10 Nov 2011 23:02:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2011/11/11/159944.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/159944.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2011/11/11/159944.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/159944.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/159944.html</trackback:ping><description><![CDATA[<div><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "></p><div><a href="http://www.phocean.net/2006/12/06/slow-performance-in-vmware-using-ubuntu.html">http://www.phocean.net/2006/12/06/slow-performance-in-vmware-using-ubuntu.html</a></div><span style="font-size: 14pt; "><br /><br />Hmm the output from the system monitor is weired, you can&#8217;t have a process not using memory at all (the virtual memory is huge but matches with the way you configured your VM).</span><p>&nbsp;</p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">I advise you to use &#8220;top&#8221; in a terminal, as root, to get some reliable info.</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">Concerning your performance problem, you should not swap within the virtual machine with such an impressive of allocated memory.</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">How much physical memory do you have ? Maybe, the problem is that your machine lacks of memory and makes your Ubuntu swapping&#8230;</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">To boost performance, I use the following settings :</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">(1) in the options of VMWare, I deactivate &#8220;taking snapshots in the background&#8221; and, in the memory section, I force all the virtual memory to fit in the available physical memory (no swap)</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">(2) I also adjust the swappiness parameter of the linux kernel.</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">By default, the linux kernel uses quite often the swap even if you still have plenty of free memory.</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">You can change this behaviour with this command :</span><br /><span style="font-size: 14pt; ">echo &#8220;15&#8243; &gt; /proc/sys/vm/swappiness</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">I use &#8220;15&#8243;, which gives a pretty high priority to the physical memory, before the kernel uses the swap. By default, the value is 60. The higher, the more it will use the swap.</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">After testing, you can make it permanent by adding such a line at the end of /etc/sysctl.conf :</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">vm.swappiness = 15</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">(3) I would, anyway, just try to reduce the memory amount you allocate to you VM. Just in case.</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">(4) Also check the processes runing on your XP when it is slow ! Are you sure that your Windows image did not get infected by some trojan or virus ?</span></p><p style="margin-top: 0.5em; margin-right: 0px; margin-bottom: 0.5em; margin-left: 0px; color: #222222; font-family: tahoma, geneva, sans-serif; font-size: 10px; line-height: 14px; background-color: #ffffff; "><span style="font-size: 14pt; ">(5) For graphics, did you set up VMWare tools ?</span></p></div><img src ="http://www.cppblog.com/tommy/aggbug/159944.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2011-11-11 07:02 <a href="http://www.cppblog.com/tommy/archive/2011/11/11/159944.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>my machinery-simulation-software "CMaxSpore"</title><link>http://www.cppblog.com/tommy/archive/2011/11/03/159549.html</link><dc:creator>Tommy Liang</dc:creator><author>Tommy Liang</author><pubDate>Thu, 03 Nov 2011 03:14:00 GMT</pubDate><guid>http://www.cppblog.com/tommy/archive/2011/11/03/159549.html</guid><wfw:comment>http://www.cppblog.com/tommy/comments/159549.html</wfw:comment><comments>http://www.cppblog.com/tommy/archive/2011/11/03/159549.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/tommy/comments/commentRss/159549.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/tommy/services/trackbacks/159549.html</trackback:ping><description><![CDATA[here is the screen capture video demo:&nbsp;<br /><a href="http://youtu.be/CO0mHBMWmmg">http://youtu.be/CO0mHBMWmmg</a><br /><br />Qt/OpenGL UI imitate UNITY<br /><img src="http://www.cppblog.com/images/cppblog_com/tommy/307.png" width="554" height="291" alt="" /><br /><div><p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">Dynamic&nbsp;3D&nbsp;view&nbsp;control</span></p><p style="margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Easy&nbsp;to&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">rotate&nbsp;(</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">yaw/pitch)&nbsp;parts&nbsp;with&nbsp;mouse&nbsp;left&nbsp;button&nbsp;and&nbsp;pan&nbsp;with&nbsp;right&nbsp;button.&nbsp;W</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">ith</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">&nbsp;the&nbsp;mouse&nbsp;wheel&nbsp;you&nbsp;can&nbsp;scale&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">it</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">&nbsp;and&nbsp;double&nbsp;clicking&nbsp;to&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">locate</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">&nbsp;the&nbsp;central&nbsp;point&nbsp;of&nbsp;the&nbsp;view;</span></p><p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">Easy&nbsp;manipulate&nbsp;apparatus</span></p><p style="margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Rotate&nbsp;or&nbsp;move&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">individual</span>&nbsp;<span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">parts</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">&nbsp;with&nbsp;mouse</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">,&nbsp;the</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">&nbsp;parts&nbsp;can&nbsp;move&nbsp;correctly&nbsp;according&nbsp;to&nbsp;the&nbsp;joint&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">relations,&nbsp;current&nbsp;support&nbsp;pairs:&nbsp;prismatic</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">-pair</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&nbsp;and&nbsp;revolute</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">-</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">turning</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">-pair</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">;</span></p><p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Wingdings'; ">l&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">Free&nbsp;room&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Verdana'; ">dimension</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">&nbsp;set&nbsp;up</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">room</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&#8217;</span><span style="color: #444444; font-size: 10pt; font-family: 宋体; ">s&nbsp;width、length、height&nbsp;and&nbsp;other&nbsp;parameters&nbsp;can&nbsp;be&nbsp;manually&nbsp;setup&nbsp;and&nbsp;modified;<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/tommy/826.png" width="554" height="390" alt="" /><br /><br /></span></p><div><p style="margin-left:21.0000pt; text-indent:-21.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="font-weight: bold; font-size: 10pt; font-family: Wingdings; ">l&nbsp;</span><span style="font-weight: bold; font-size: 10pt; ">Parts&nbsp;Library</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="font-size: 10pt; ">Apparatus&nbsp;parts&nbsp;can&nbsp;be&nbsp;dragged&nbsp;from&nbsp;the&nbsp;</span><span style="font-size: 10pt; font-family: Verdana; ">&#8220;</span><span style="font-size: 10pt; ">parts&nbsp;library</span><span style="font-size: 10pt; font-family: Verdana; ">&#8221;</span><span style="font-size: 10pt; ">&nbsp;into&nbsp;the&nbsp;3D&nbsp;</span><span style="font-size: 10pt; font-family: Verdana; ">scene,&nbsp;and</span><span style="font-size: 10pt; ">&nbsp;assembled&nbsp;to&nbsp;the&nbsp;</span><span style="font-size: 10pt; font-family: Verdana; ">&#8220;</span><span style="font-size: 10pt; ">anchor&nbsp;points</span><span style="font-size: 10pt; font-family: Verdana; ">&#8221;</span><span style="font-size: 10pt; ">&nbsp;of&nbsp;the&nbsp;pre-assembled&nbsp;</span><span style="font-size: 10pt; font-family: Verdana; ">parts;</span><span style="font-size: 10pt; ">&nbsp;assembled&nbsp;parts&nbsp;are&nbsp;removable;<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/tommy/1013.png" width="554" height="309" alt="" /><br /><br /></span></p><div><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">Part&nbsp;joints&nbsp;dynamically&nbsp;changed</span>&nbsp;</p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Change&nbsp;the&nbsp;part&nbsp;joints&nbsp;motion-constraint-parameters&nbsp;dynamically,&nbsp;like&nbsp;the&nbsp;hanging&nbsp;arm</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&#8217;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">s&nbsp;rotation&nbsp;angle&nbsp;range,&nbsp;i.e.&nbsp;change&nbsp;it&nbsp;from&nbsp;360&nbsp;degree&nbsp;to&nbsp;90&nbsp;degree,&nbsp;the&nbsp;scene&nbsp;will&nbsp;respond&nbsp;the&nbsp;changed&nbsp;data&nbsp;immediately;<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/tommy/1256.png" width="554" height="310" alt="" /><br /><br /></span></p><div><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="font-weight: bold; font-size: 10pt; font-family: Symbol; ">&#183;&nbsp;</span><span style="font-weight: bold; font-size: 10pt; font-family: Verdana; ">Collision&nbsp;detection</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="font-size: 10pt; ">I</span><span style="font-size: 10pt; font-family: Verdana; ">f&nbsp;the&nbsp;apparatus&nbsp;collide&nbsp;with&nbsp;each&nbsp;other&nbsp;or&nbsp;the&nbsp;room&#8217;</span><span style="font-size: 10pt; ">s&nbsp;walls,&nbsp;it&nbsp;will&nbsp;turn&nbsp;red&nbsp;to&nbsp;indicate&nbsp;the&nbsp;collision&nbsp;occurring&nbsp;as&nbsp;to&nbsp;adjust&nbsp;the&nbsp;equipment</span><span style="font-size: 10pt; font-family: Verdana; ">&#8217;</span><span style="font-size: 10pt; ">s&nbsp;position;<br /><br /><img src="http://www.cppblog.com/images/cppblog_com/tommy/1432.png" alt="" /><br /><br /></span></p><div><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Verdana'; ">Real-time</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">&nbsp;dimension&nbsp;measure</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">User can&nbsp;switch&nbsp;to&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&#8220;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Dimension&nbsp;measure&nbsp;mode</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&#8221;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">&nbsp;to&nbsp;measure&nbsp;chosen&nbsp;points&nbsp;from&nbsp;apparatus&nbsp;to&nbsp;the&nbsp;wall/floor/ceiling&nbsp;or&nbsp;points&nbsp;on&nbsp;the&nbsp;other&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">apparatus</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">,&nbsp;when&nbsp;press&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&#8220;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Ctrl</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&#8221;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">,&nbsp;<br />the&nbsp;scene&nbsp;will&nbsp;enter&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&#8220;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">transparency&nbsp;dimension&nbsp;measure&nbsp;mode</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&#8221;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">,&nbsp;when&nbsp;user&nbsp;move&nbsp;or&nbsp;rotate&nbsp;the&nbsp;apparatus&nbsp;parts,&nbsp;related&nbsp;dimension&nbsp;numbers&nbsp;will&nbsp;change&nbsp;accordingly;<br /><br /></span></p></div><span style="font-size: 10pt; "><img src="http://www.cppblog.com/images/cppblog_com/tommy/1781.png" width="554" height="423" alt="" /><br /><br /></span><div><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">Apparatus&nbsp;library&nbsp;management</span></p><p style="margin-left:18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">user&nbsp;can&nbsp;manage&nbsp;the&nbsp;parts&nbsp;category&nbsp;hierarchy&nbsp;as&nbsp;deep&nbsp;as&nbsp;needed;&nbsp;support&nbsp;OBJ&nbsp;file&nbsp;imported&nbsp;into&nbsp;the&nbsp;library&nbsp;and&nbsp;preview;&nbsp;user&nbsp;can&nbsp;manage&nbsp;the&nbsp;part</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">&#8217;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">s&nbsp;motion-pair&nbsp;parameter&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">dynamically</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">;</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">Data&nbsp;export</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Scene&nbsp;can&nbsp;be&nbsp;saved&nbsp;as&nbsp;project&nbsp;file&nbsp;and&nbsp;reopen;&nbsp;the&nbsp;structure&nbsp;of&nbsp;the&nbsp;scene&nbsp;including&nbsp;all&nbsp;the&nbsp;apparatus&nbsp;parameters&nbsp;can&nbsp;be&nbsp;exported&nbsp;to&nbsp;word/excel&nbsp;files;&nbsp;the&nbsp;scene&nbsp;can&nbsp;also&nbsp;be&nbsp;exported&nbsp;to&nbsp;<br />an&nbsp;independent&nbsp;window</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">s&nbsp;executable&nbsp;file&nbsp;(exe</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">,&nbsp;prototype&nbsp;written&nbsp;with&nbsp;MFC</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">),&nbsp;when&nbsp;opened,&nbsp;user&nbsp;can&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">also&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">control&nbsp;the&nbsp;scene&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">and&nbsp;the&nbsp;apparatus&nbsp;without&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">CMaxSpore&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">product&nbsp;installed;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; "><br /></span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">The&nbsp;exported&nbsp;executable&nbsp;support&nbsp;only&nbsp;observation&nbsp;but&nbsp;not&nbsp;parameter&nbsp;manipulation;<br /><br /></span></p></div><span style="font-size: 10pt; "><img src="http://www.cppblog.com/images/cppblog_com/tommy/2445.png" width="554" height="371" alt="" /><br /><br /></span><div><p style="margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">Technical&nbsp;Key&nbsp;points</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Qt&nbsp;library&nbsp;(open&nbsp;source&nbsp;version)</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">OpenGL</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Computer&nbsp;graphics</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">OOA,OOD</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">M</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">ulti-threading</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">MFC/Win32&nbsp;SDK</span></p><p style="margin-left:4.9000pt; text-indent:-4.9000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">Constructing&nbsp;features</span></p><p style="margin-bottom:0pt; margin-top:0pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">NVidia&nbsp;Optix-Real-time-ray-tracing&nbsp;engine embed</span>&nbsp;</p></div></div></div><span style="font-size: 10pt; "><img src="http://www.cppblog.com/images/cppblog_com/tommy/2633.png" width="502" height="318" alt="" /><img src="http://www.cppblog.com/images/cppblog_com/tommy/2634.png" width="405" height="258" alt="" /><br /><br /></span><div><div><p style="margin-left:4.9000pt; text-indent:-4.9000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'Verdana'; ">E</span><span style="mso-spacerun:'yes'; color:#444444; font-weight:bold; font-size:10.0000pt; font-family:'宋体'; ">xploring&nbsp;ideas</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">I</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">mport&nbsp;rooms&nbsp;from&nbsp;AutoCAD&nbsp;DWG&nbsp;file</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">;&nbsp;(</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">AutoCAD&nbsp;API/Pattern&nbsp;recognition</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">)</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Export&nbsp;scene&nbsp;to&nbsp;AutoCAD&nbsp;DWG&nbsp;file&nbsp;directly;</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">JavaScript&nbsp;engine&nbsp;embed;</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Verdana'; ">Apparatus&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">parts&nbsp;data&nbsp;network&nbsp;storage&nbsp;and&nbsp;multiple-user&nbsp;rights&nbsp;control;</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">I18;</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Augmented&nbsp;reality&nbsp;support;</span></p><p style="margin-left:36.0000pt; text-indent:-18.0000pt; margin-bottom:5.0000pt; margin-top:5.0000pt; text-align:left; line-height:15.0000pt; "><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'Symbol'; ">&#183;&nbsp;</span><span style="mso-spacerun:'yes'; color:#444444; font-size:10.0000pt; font-family:'宋体'; ">Flash&nbsp;publishing</span></p></div></div><p>&nbsp;</p></div><p>&nbsp;</p></div><img src ="http://www.cppblog.com/tommy/aggbug/159549.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/tommy/" target="_blank">Tommy Liang</a> 2011-11-03 11:14 <a href="http://www.cppblog.com/tommy/archive/2011/11/03/159549.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>