作者归档:jimmy

定位崩溃UIKit`+[UIViewController _viewControllerForFullScreenPresentationFromView:]:

问题描述
最近在开发中遇到了一个crash,该crash可以稳定复现,复现的步骤如下,
1 在一个navigation controller中,push一个包含scroll view的view controller
2 在该view controller中,点击一个按钮,然后push另一个包含了scroll view新的view controller。
3 pop当前的view controller,回到步骤1中的view controller
4 按iOS的status bar,此时,应用crash

遇到了可以稳定复现的crash,我的第一反应就是查看crash log。然而,令我感到意外的是,crash log显示,错误为
EXC_BAD_ACCESS (SIGBUS)
KERN_EXCEPTION_PROTECTED
crash log显示对应的代码为UIKit`+[UIViewController _viewControllerForFullScreenPresentationFromView:]:

崩溃时候的call stack

这岂不是表明,crash的代码位于iOS的系统中,而不是我自己写的代码,难道viewControllerForFullScreenPresentationFromView这个方法有什么bug?

但是,考虑到这个crash可以稳定复现,我仍然觉得这应该是我的某处代码没有写好的缘故,而不是iOS系统的bug。然而,从crash log无法直接定位到我的代码的具体位置,我一时也没有好的线索去定位错误代码。

为了找寻线索,我搜索了stackoverflow,然后还真的发现了一个类似的问题 http://stackoverflow.com/questions/30080990/ios-app-crashes-with-exc-bad-access-sigsegv-on-ipad-ios-7-1-1-device 。

这个问题的crash log如下
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000c
Triggered by Thread: 0

Thread 0 Crashed:
0 libobjc.A.dylib 0x3b3a1626 objc_msgSend + 6
1 UIKit 0x33301b46 +[UIViewController _viewControllerForFullScreenPresentationFromView:] + 174
2 UIKit 0x33301614 -[UIWindow _scrollToTopViewsUnderScreenPointIfNecessary:resultHandler:] + 428
3 UIKit 0x3330143e -[_UIScrollsToTopInitiatorView touchesEnded:withEvent:] + 210
4 UIKit 0x3330134e -[UIStatusBar touchesEnded:withEvent:] + 334
5 UIKit 0x33255790 forwardTouchMethod + 228
6 UIKit 0x3310371c -[UIWindow _sendTouchesForEvent:] + 524
7 UIKit 0x330fe6e6 -[UIWindow sendEvent:] + 754
8 UIKit 0x330d38e8 -[UIApplication sendEvent:] + 192
9 UIKit 0x330d1f92 _UIApplicationHandleEventQueue + 7098
10 CoreFoundation 0x3087e258 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 12
11 CoreFoundation 0x3087d726 __CFRunLoopDoSources0 + 202
12 CoreFoundation 0x3087bf1a __CFRunLoopRun + 618
13 CoreFoundation 0x307e6f0a CFRunLoopRunSpecific + 518
14 CoreFoundation 0x307e6cee CFRunLoopRunInMode + 102
15 GraphicsServices 0x356e065e GSEventRunModal + 134
16 UIKit 0x33132168 UIApplicationMain + 1132
17 MyApp 0x0029c0a0 main (main.m:16)
18 libdyld.dylib 0x3b8a4ab4 start + 0

我发现,这个crash log和我的crash log几乎一模一样,尽管这个stackoverflow的问题并没有人回答,然而,问题的一个comment还是给了我线索。

It’s not a memory leak problem. Somewhere you seem to be trying to access a deallocated object. – rmaddy May 6 ’15 at 18:28

这么说,我遇到的crash也应该是deallocated object导致的了,那么,如果我能够定位到具体是哪一个deallocated object的话,那就可以进一步缩小排查的代码范围了。这时候,我应该用NSZombieEnabled选项来调试我的app了。

首先,启用Enable Zombie Objects选项。
NSZombieEnabled
我们都知道,iOS的运行时是用C和Objective C实现的,每一个对象都采用引用计数进行内存管理,如果某一个对象的引用计数为0了,那么该对象的内存就会被释放掉 ,而我们启用了Zombie Objects后,一个对象引用计数为0的时候,这个对象会被转换为一个Zombie对象,而不是直接释放掉,如果你向一个zombie对象发消息,那么调试器就会捕捉到这个操作,你就可以进一步定位具体错误了。

接下来,我用Enable Zombie Objects选项启动并调试app并且很容易地获取到了这条有效的调试信息。

[UIScrollView retain]: message sent to deallocated instance 0x12eda1e00

从这条调试信息来看,问题与我的代码中声明的某一个UIScrollView对象有关,可是我怎么知道这是哪一个scroll view对象呢,这个scroll view对象在我的代码中用什么属性,什么变量去引用的呢?

我仔细观察了对应的源文件,我发现只有三个View Controller的属性的类型是UIScrollView,为此,我在dealloc的方法中设置了断点,在断点上获取对应的类型为UIScrollView的属性的指针,并记录下来,然后将记录下来的指针与Zombie对象的指针进行对比,经过多次反复的重现这个crash,我终于发现原来crash与是一个名为scrollView1的属性有关,每一次发生crash,deallocated instance一定是scrollView1这个属性的指针,无一例外。

我经过仔细对比,反复代码审查,终于发现了一处潜在的问题,那就是,我会在viewDidLoad之后,viewDidAppear之前就对scrollView执行Scroll操作,我总感觉有些不妥,似乎应该在viewDidAppear之后才能对scrollView进行scroll的。

我对代码进行了改动,凡是要对scrollView执行scroll动作的代码(即调用了UIScrollView setContentOffset方法),都一律延后到viewDidAppear之后进行。

修改代码后,我再次进行测试,这下子发现app不再崩溃了,运行十分正常,问题解决。

结论,千万不要在viewDidAppear之前,或者说,更准确的说,千万不要在当前的ViewController的view.window属性为nil的时候对UIScrollView进行setContentOffset操作,否则,你会发现你遇到了crash,并且crash的位置是UIKit`+[UIViewController _viewControllerForFullScreenPresentationFromView:]:。

Xcode 8 Beta 2转换原Swift 2.2代码到Swift 3.0后报错Found an unexpected Mach-O header code: 0x72613c21

今天试用了Xcode 8 Beta 2,尝试将之前Swift 2.2的代码转换为Swift 3.转换的过程一波三折,Swift 3改动十分大。

诸如dispatch_after这些在Swift 3中都改成了DispatchQueue.main.after这种形式,其次,很多Objc的对象也改了翻译的名字,如Swift 2.2中UIScreen.mainScreen()变成了UIScreen.main()。其实这些都还好,Xcode都可以帮我自动转换好。

还有一个令人非常烦恼的就是objc代码的导入机制的变化,如果你有很多旧的代码还没有用nonnull这些关键字修饰objc的属性和方法的话,你就会发现,原来在Swift 2.2中,导入的objc属性或者方法参数是默认unwrapped的,到了Swift 3中,变成了默认不unwrapped了,而这些代码你必须手动去修改。

然而,最令我感到意外的是,到了最后,Xcode在copy swift libraries的时候,又报了错误
error: Found an unexpected Mach-O header code: 0x72613c21

用这个错误信息去找,看上去最符合的信息就是https://github.com/CocoaPods/CocoaPods/issues/5598,该issue中提到要设置ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES=NO,然而,我的所有的build settings都已经是ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES=NO了,可是Xcode还是会报错Found an unexpected Mach-O header code: 0x72613c21。最后,我只能认为是Xcode 8 Beta 2的一个bug了。

Swift 从1到2,从2到3,都完全没有考虑向后兼容(Backward Compatibility),这只能说明Swift其实连个半成品都不算,各位学习Swift可以,千万不要用在实际的工程中,否则,坑死你。

应用退出登录,数据丢失,原来是iOS系统的bug,NSUserDefaults内容随机消失

最近,我突然发现用着用着很多应用就要我重新登录了,我自己的app在调试的时候,也经常发现原来保存的登录状态也消失了。经过调查,我发现,原因在于保存在NSUserDefaults中的登录信息没了,而保存在keychain和文件中的信息还有。

经过查找,我发现了如下信息,原来是iOS 9.3的一个bug,应用用于保存信息的NSUserDefaults的内容会随机消失。
https://forums.developer.apple.com/thread/44264

iOS 9.3.1 NSUserDefaults Wiped Bug?

elementarteilchen
May 6, 2016 5:11 AM
(in response to staminajim_sg)
Yes. It seems that the iOS just “forgets” to load the data sometimes. If this happens in my own App while debugging, I can easily kill the App and prevent that it will change the userdefaults, and the next time I lanuch it again, the settings are usually loaded just fine. The big problem is that when you are not debugging your own Apps, you do not have a chance to kill an App before it save any settings, and when an App does this, the old settings are overwritten and lost forever.
(给staminajim_sg的回复)
是的。这看起来是iOS似乎有时候忘记及时加载数据了。我在调试的时候常常发现这个现象发生,在这种情况下,我可以用杀掉app的方式防止我的app执行对NSUserDefaults的修改操作,这样子,下一次我再启动app,原来的设置都还在而且也会正确加载。最大的问题是,如果你不是在调试你的App,你就没有办法像我一样杀死App,这就导致App会执行写操作,原有的设置就会被覆盖掉了。

Rygen
May 27, 2016 6:10 AM
(in response to elementarteilchen)
Also facing the same issue since 9.3, and now it persists on 9.3.2.
I’ve had this issue happen with a first party app as well – Weather. It lost all the saved cities, about one month ago.
Whatsapp is by far the worst in terms of data loss. You can’t avoid some of it even if you’re obsessively backing it up to iCloud every single time you use the app.
I know of one person which is not using the iPhone as a development device and is also having the same problem, so this NSUserDefaults issue is probably not related to that.
Which iPhone models are you seeing the issue on? Mine is a 5S.

I’ve submitted a bug report to Apple.
(给elementarteilchen的回复)
我从iOS 9.3版本开始就遇到这样的问题,现在已经升级到9.3.2了,问题依旧存在。
我最开始遇到这个问题,是一个月以前,在我的天气应用上,我的天气应用中保存的城市列表都消失了。
Whatsapp则是受到影响最大的,即便你经常通过iClound备份,你的数据也会丢失。
我知道一个案例,一个用户并不是将他的/她的iPhone作为开发设备,而他/她也遇到了类似的现象,这表明NSUserDefaults问题并不是因为iPhone被设置为开发设备的缘故。
大家在那些iPhone型号上遇到这个问题了?我的是iPhone 5S

ChaoticBox
Jun 19, 2016 1:06 AM
(in response to NeilFau)
I’ve been seeing this as well but figured out a workaround for my own apps: If my keys aren’t found, call resetStandardUserDefaults and try again. It shouldn’t hurt to repeat that a few times before bailing and assuming it’s a first-run, but so far it has always worked after the first reset.
(给NeilFau的回复)
我也遇到了相同的问题,不过我找到了一个变通的方法。如果我的应用在启动的时候发现某个键值对应的值不存在,那么我会首先调用resetStandardUserDefaults,然后接着再试着获取该值。重复几次resetStandardUserDefaults的操作,如果这样仍然无法取到相应的值,那么可以认定这是首次运行。这样的操作并不繁琐复杂,但是截至到目前位置,我发现这个方案是有效的。

alexfit
Jul 6, 2016 12:30 AM
(in response to NeilFau)
This has been happening to me for the last few months. By FAR, the most distressing bug I’ve encountered on iOS as a user. Can’t use What’s App, as I’m constantly losing chat history. Have to log in again to Evernote, Instagram. Settings and tips for many apps reset and I’m sent back to onboarding screens.

For the first time, I’ve lost all trust in my iPhone. A thought of getting a “reliable” Android phone crossed my mind…

I hope this is getting fixed, soon.
(给NeilFau的回复)
这个问题在最近几个月一直困扰着我。到目前为止,这是我见过的最令人烦恼的一个iOS的bug。我不能用Whatsapp,因为我经常会丢失聊天记录。我不得不重复登录Evernote,Instagram。许多应用的设置和提示都被重置了,这导致我每次启动都见到欢迎界面。

这是我首次丧失了对iPhone的信任,我已经开始考虑买一个可靠的安卓手机了。

希望这个bug能够被尽快修复。

iOS UILabel显示了重叠文字(gets combined, superimposed, overlapped)

Screen Shot 2016-06-30 at 12.07.11 AM

今天调试遇到了一个问题,上图是一个UILabel的截图,该UILabel的text属性实际上是“21张”,然而,如果你仔细看这张截图的话,似乎可以看出,大约是一个“21张”文字的渲染结果叠加了一个“10张”文字的渲染效果。通常,出现这种情况,我的第一反应是我是不是重复的addSubView了,导致多个UILabel相重叠了。

然而,仔细检查了代码,并且用Reveal查看了View层次结构后,我确认了一点,没有多个UILabel重叠,确实只有那一个UILabel并且就是该UILabel把“21张”渲染成了上图的模样。

最后发现,问题在于UILabel的backgroundColor不能设置为nil,也不能设置为透明色。只要给UILabel设置了背景色,这个问题就解决了。

而且,我发现这不是个例,早在2012年,2013年就已经有人遇到这个问题,而且,根据Stackoverflow.com提供的线索,这似乎是iOS 5开始才有的问题(看后面的If I try it on an iPhone 4, the previous text of the label doesn’t disappear)。如今,iOS 10都快要正式版了,没想到这个问题还在。

最后,给大家忠告,一定要仔细检查UILabel的背景,千万不要把backgroundColor设置成透明色或者nil。

参考资料如下

http://www.cocoachina.com/bbs/read.php?tid=257298
主题 : UILabel背景为透明时,刷新文字会和旧文字重叠
楼主 :
发表于: 2013-03-06 17:04

把label的背景色从默认(也就是clear color)设成其他颜色,问题就解决了。

如果有时候需要label背景透明,那又该怎么办呢?

http://stackoverflow.com/questions/2271144/setting-transparent-background-for-uilabel-for-iphone-application

Nullifying the backgroundColor works fine at first, but if you subsequently change the label’s text, the new text will be superimposed on the old. Very weird. – Wienke Sep 27 ’12 at 19:50 (编者注:这是2012年9月27日的评论,原问题发表于2010年4月29日。将backgroundColor属性设置为nil,最开始你会发现能如你所愿,然后,随后你就会发现,如果你更改了label的text属性,新的文本会重叠在旧的文本之上。非常奇怪。)

http://stackoverflow.com/questions/10373119/uilabels-new-text-gets-combined-with-previous-text-when-testing-on-real-iphone#

I have some UILabel objects in my app, and I change their value when a button is pressed. It works fine in the simulator and on old iPhones, but If I try it on an iPhone 4, the previous text of the label doesn’t disappear, it shows behind the the new text (well, sometimes it disappears and only the correct text appears, but most of the times it doesn’t work right). (编者注:提问者说道,在模拟器和比iPhone 4老的iPhone上,一切正常,可是,如果是iPhone 4,UILabel设置了新的文本的话,旧的文本仍然显示在新的文本的后面,这正如本文最开始的截图所显示的那样。)
asked Apr 29 ’12 at 14:53

I can tell you it’s not a bug, and not common. I’m guessing that you have a transparent background behind UILabel? And redraw might not be correctly handled in the background view. You might want to post more about your view hierarchy. – He Shiming Apr 29 ’12 at 17:08 (编者注:后面有人评论,我可以告诉你,这不是bug,也不常见。 我猜测你的UILabel一定有一个透明的背景,而redraw操作或许不能正确处理透明背景的情况。你或许应该告诉大家你的视图层次结构的详细信息。)

cellForRowAtIndexPath: not called,cellForRowAtIndexPath不被调用

今天遇到了一个神奇的事情
tableView:cellForRowAtIndexPath:这个方法,我的TableViewDataSource里已经实现了,可是,无论如何,都不会被调用。
我在numberOfRowsInSection和numberOfSectionsInTableView和cellForRowAtIndexPath三处都设置了断点,然而,前两个方法都得到了调用,唯独最后一个cellForRowAtIndexPath,无论如何都不会被调用。

我可以确定numberOfRowsInSection和numberOfSectionsInTableView都返回了非0的值。

最后我发现,我的DataSource还实现了
sectionIndexTitlesForTableView

titleForHeaderInSection
两个方法,只不过我都在这两个方法中返回了nil。

最后我删除了这两个方法的代码,结果,cellForRowAtIndexPath被系统调用了,我的TableView的内容也可以正常显示了!!!

目前我也不知道怎么回事,因为,sectionIndexTitlesForTableView和titleForHeaderInSection的返回值的声明是nullable的,而且之前这两个方法也是这么实现了,并且上个月,同样的情况,cellForRowAtIndexPath就被系统调用了。

这个事情实在让我百思不得其解,所以写一篇blog记录下来。

在OSX 10.11 El Captain上安装pybonjour时遇到dlopen(libSystem.B.dylib, 6): image not found错误

上一篇讲到,我需要安装PonyDebugger,而安装PonyDebugger需要安装pybonjour,然而,安装pybonjour时,又遇到了错误,错误信息如下,
Traceback (most recent call last):
File “setup.py”, line 32, in
import pybonjour
File “/Users/huangshaojun/Downloads/Eichhoernchen-pybonjour-c63b48c/pybonjour.py”, line 109, in
_libdnssd = ctypes.cdll.LoadLibrary(_libdnssd)
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py”, line 443, in LoadLibrary
return self._dlltype(name)
File “/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py”, line 365, in __init__
self._handle = _dlopen(self._name, mode)
OSError: dlopen(libSystem.B.dylib, 6): image not found

我到github上也找到了对应的Issue 192 https://github.com/square/PonyDebugger/issues/192
Issue提到的解决方法是

well, okay i had to do a brew install python

即,不要用OSX内置的python,而用brew新安装一个python。

我并不想再新安装一个新的python,我还是希望用OSX内置的python,为此,我根据
http://stackoverflow.com/questions/32905322/oserror-dlopenlibsystem-dylib-6-image-not-found
的提示,修改了pybonjour.py

if sys.platform == 'darwin':
        _libdnssd = 'libSystem.B.dylib'
    else:

改为

if sys.platform == 'darwin':
        _libdnssd = '/usr/lib/libSystem.B.dylib'
    else:

这样用OSX内置的python就可以正确安装pybonjour了。

PonyDebugger安装错误:Could not find a version that satisfies the requirement pybonjour==1.1.1

之前一直用Reveal,不过Reveal只能查看View Hierarchy,而我听说PonyDebugger不仅仅可以查看View Hierarchy,还能debug network traffic和view core data,所以决定也集成PonyDebugger。

到PonyDebugger的主页(https://github.com/square/PonyDebugger)一看,发现README中有一个Quick Start,这个Quick Start提到首先要运行如下代码安装ponyd

curl -s https://cloud.github.com/downloads/square/PonyDebugger/bootstrap-ponyd.py | \
  python - --ponyd-symlink=/usr/local/bin/ponyd ~/Library/PonyDebugger

我运行了以后,遇到如下错误

Collecting pybonjour==1.1.1 (from ponyd)
  Could not find a version that satisfies the requirement pybonjour==1.1.1 (from ponyd) (from versions: )
No matching distribution found for pybonjour==1.1.1 (from ponyd)
Traceback (most recent call last):
  File "", line 2462, in 
  File "", line 946, in main
  File "", line 1794, in after_install
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 540, in check_call
    raise CalledProcessError(retcode, cmd)

随后,我用关键字

Could not find a version that satisfies the requirement pybonjour==1.1.1 

进行搜索,发现了Issue #186 https://github.com/square/PonyDebugger/pull/186,此issue表明pybonjour的问题已经于2016年2月27日解决了。可是,我为什么仍然遇到了这个问题呢。

接下来,Issue 185解决了我的疑惑 https://github.com/square/PonyDebugger/issues/185,其中 justinseanmartin 在3月15日提到

I was able to clone and then install using python setup.py install. It isn't as convenient as the command from the readme, will look into getting the script fixed up as well.

Issue 188 https://github.com/square/PonyDebugger/issues/188 中,justinseanmartin也提到了,

Dupe of #100. You should be unblocked by:

git clone git@github.com:square/PonyDebugger.git
cd PonyDebugger
python setup.py install

Please confirm this works for you. I've logged #189 to track fixing the install script and/or instructions.

这说明,pybonjour问题的解决方案,还没有应用到https://cloud.github.com/downloads/square/PonyDebugger/bootstrap-ponyd.py,所以,用Quick Start的方式安装仍然有问题,我们目前还是需要把PonyDebugger的git库clone到本地,再进行安装。

评高考题目:“老腔”何以令人震撼

2016年北京的高考作文题目为二选一,其中一题就是“‘老腔’何以令人震撼”。作家陈忠实先生在《白鹿原上奏起一曲老腔》中给老腔以“撼人肺腑”和“酣畅淋漓”的高度评价。然而,我个人听了电影《白鹿原》中的老腔后,却感到“憾人肺腑”的难听,一分钟都听不下去了。

老腔之所以能令人震撼,我认为,这是因为“老腔”这种曲艺的形式,让人要么如陈忠实或者濮存昕这样的人感觉到震撼和好听,要么让如我一样的民众感到十分难听,根本不能接受。一种艺术形式,能达到这种程度,说明它必然极度满足了一批人的体验,这就导致了其他人会根本无法接受。

两个不同的语言,都叫做Swift,而人们熟知的是苹果的Swift

2014年,苹果发布了Swift语言,随后大量的示例代码都改用Swift语言编写,许多新的iOS和Mac项目也都用了Swift语言。从2014年到2016年,Swift语言已经从1.0发展到了2.2版本,3.0也已经在roadmap上了。

然而,有多少人知道,其实,名称叫做“Swift”的语言,其实不止一个呢?
我们先看看Apple的Swift
https://swift.org/ – We are excited by this new chapter in the story of Swift. After Apple unveiled the Swift programming language, it quickly became one of the fastest growing languages in history.

我们在看看诞生更早的Swift语言。
http://swift-lang.org/main/index.php – A simple tool for fast, easy scripting on big machines.
Swift: A language for distributed parallel scripting (2011) [pdf]

我们不难发现,distributed parallel scripting的Swift,至少在2011年就已经在科学界广泛使用了。而苹果的Swift,至少在2014年以前还是未公布状况。

我们再来看看图标
Apple Swift
Swift logo_swift
图标中的雨燕是不是也很相似呢?一个向下飞,一个向上飞。

iOS应用的糟糕例子:口碑外卖的用户体验越来越糟,这是把用户往饿了么赶

最近几年,O2O,特别是外卖,已经形成了白热化的砸钱补贴营销的战场,外卖市场上,饿了么,美团,口碑和百度四家基本上成为外卖的主流平台了,外卖配送方面,百度自己做了配送,美团也有自己的专送,饿了么做了蜂鸟配送,此外,还有一个达达,也是做了配送,同时达达也做了一个叫做派乐趣的外卖平台。

大战已经进行了快两年了,百度外卖,饿了么,美团和口碑这四家,现在也变成了三家,即口碑和饿了么合并,口碑外卖事实上被阿里巴巴抛弃了。

为什么说口碑事实上已经被抛弃了呢。

打开了最新更新的口碑外卖客户端,第一个感觉就是,怎么全都变成H5页面了?口碑外卖底部的tab bar,只有“外卖”、“订单”和“我的”三个按钮,我在这三个tab之间切换的时候,明显感觉到tab bar会闪一下,然后整个app中间有一个浏览器在加载某个页面。这样的感受让人感到非常糟糕。

到口碑外卖的某个店里一看,发现这个店在口碑只有三个宝贝在卖,而在饿了么里,却有几十个,明显感觉到商家要放弃口碑的样子。

再看看近期的新闻
口碑APP订餐出现平台即将关闭提示 官方回应:商家理解有误 2016-05-03 http://www.admin5.com/article/20160503/661207.shtml
饿了么开送口碑外卖:被收购进入倒计时 2016-04-21 http://www.mnw.cn/keji/mi/1159677.html

在5月3日的新闻中,饿了么方面回应称,“商户的理解不太正确。口碑外卖的业务目前都由饿了么提供,只是如此而已。”

然而,从口碑外卖的最新的app的交互体验,以及口碑外卖在苹果的App Store的差评来看,其实饿了么和阿里巴巴都已经把口碑当成了一个弃儿,就让口碑自生自灭吧。

既然口碑外卖已经是一个弃儿,一个不值得投入资源的产品,那么,自然产品、研发、运营和测试等团队就应该从口碑撤离了。这也是为什么口碑外卖更新以后,居然成了完全的H5应用的原因。

口碑当年被阿里巴巴收购后,已经死了一次,后来做外卖,业界以为口碑又会活过来,没想到,其实口碑从来没有活过,只不过被阿里打了强心剂,回光返照一下,作了一回饿了么的陪练而已,而阿里巴巴仅仅是做了个口碑和饿了么打了一架,然后趁机投资饿了么而已。

阿里做口碑,不是为了把口碑做好,而是把口碑当做为了投资饿了么的一个资本布局的一个小棋子罢了。