注意:
从iOS 4.3开始,请参阅已接受的答案(不是最受欢迎的答案).
这个问题是关于在iPad键盘中发现的行为,如果在带有导航控制器的模态对话框中显示,它将拒绝被解雇.
基本上,如果我使用以下行显示导航控制器,如下所示:
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
Run Code Online (Sandbox Code Playgroud)
键盘拒绝被解雇.如果我注释掉这一行,键盘就会消失.
...
我有两个textFields,用户名和密码; username有一个Next按钮,密码有一个Done按钮.如果我在模态导航控制器中显示它,键盘将不会消失.
作品
broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
[self.view addSubview:b.view];
Run Code Online (Sandbox Code Playgroud)
什么都不行
broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
UINavigationController *navigationController =
[[UINavigationController alloc]
initWithRootViewController:b];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
navigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[b release];
Run Code Online (Sandbox Code Playgroud)
如果我删除导航控制器部件并将"b"作为模态视图控制器单独显示,则可以正常工作.导航控制器是问题吗?
作品
broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
b.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:b animated:YES];
[b release];
Run Code Online (Sandbox Code Playgroud)
作品
broken *b = [[broken alloc] initWithNibName:@"broken" bundle:nil];
UINavigationController *navigationController =
[[UINavigationController …
Run Code Online (Sandbox Code Playgroud) 注意:在Xcode 4.3.2上获取此信息?看看这个问题的答案.
注意:创建一个使用4.2 lib的符号链接似乎工作正常
cd /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1\ \(8C148\)/Symbols/
sudo ln -s ../../4.2\ \(8C134\)/Symbols/Developer
Run Code Online (Sandbox Code Playgroud)
从4.2.0(测试版,我相信)升级到4.2.1后,缺少libXcodeDebuggerSupport.dylib文件,导致:
warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1 (8C148)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).
Run Code Online (Sandbox Code Playgroud)
我觉得这不好.看看有问题的目录我注意到:
.../DeviceSupport/4.2 (8C134)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib
Run Code Online (Sandbox Code Playgroud)
但
.../DeviceSupport/4.2.1 (8C148)/Symbols/System/
.../DeviceSupport/4.2.1 (8C148)/Symbols/usr/
Run Code Online (Sandbox Code Playgroud)
以上两个目录组成了4.2.1文件夹中的所有内容.没有"Developer"文件夹.检查/ usr/dir,我在lib目录中找不到libXcodeDebuggerSupport.dylib文件,所以ln -s'ing不是一个选项.
值得一提的是:升级后,我插入了iPad,不得不在Xcode组织器中点击"用于开发".这样做,我收到一条关于该版本缺少符号的消息,Xcode继续生成这样的符号,然后失败了.我恢复了iPad并再次进行了"用于开发",并且没有出现任何遗漏符号......
更新:中/从无到有的Xcode开发和重新安装删除并没有解决这个问题.
更新2:我刚刚意识到重新安装Xcode后,
.../DeviceSupport/4.2 (8C134)/Symbols
Run Code Online (Sandbox Code Playgroud)
现在是一个象征性的联系,
lrwxr-xr-x 1 root admin 36 Dec 3 17:17 Symbols -> ../../Developer/SDKs/iPhoneOS4.2.sdk
Run Code Online (Sandbox Code Playgroud)
并且相关目录具有适当的文件.也许这仅仅是以同样的方式链接4.2.1目录的问题?我会尝试一下,看看Xcode是否吓坏了.如果拥有此文件的人可以提供一个非常出色的md5总和.这就是它对我说的:
$ md5 /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2\ \(8C134\)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib
MD5 (/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2 (8C134)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib)
= 08f93a0a2e3b03feaae732691f112688
Run Code Online (Sandbox Code Playgroud)
如果MD5总和与输出相同
$ md5 /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1\ \(8C148\)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib
Run Code Online (Sandbox Code Playgroud)
然后我们都准备好了.
我注意到,当连接iP*时,有几个应用程序在iTunes中具有"文件共享"功能.示例应用程序是CloudReaders,Stanza等.此界面允许用户将文件添加到应用程序并将文件从应用程序保存到其计算机.现在我在应用程序内部运行了一个HTTP服务器,允许用户通过Wi-Fi向其添加文件,但我也想支持上述方法.
感谢Art Gillespie,我得到了这个工作.最近,我重新命名了我的项目,并最终不得不再次挖掘一下,以弄清楚如何重新启用它,因为它消失了.
这就是你如何做到的.
UIFileSharing
.它应该被列为"应用程序支持iTunes文件共享"之类的东西.build/Release-iphoneos/
项目的文件夹,将appname文件(不是那个.dSYM
)拖到iTunes.如果要求更换,请单击"是".我正在开发的应用程序有自己的文件的自定义文件格式,我希望能够使用iOS的"打开..."功能,让用户例如通过电子邮件发送文件,然后直接打开它在应用程序中.
我已经在Info.plist文件中添加了CFBundleDocumentType内容,但问题是LSItemContentTypes.根据我的阅读,我需要提供实际文件作为UTI,而不是仅仅说".myfileextension",我找不到很多关于如何在iOS应用程序中创建UTI的内容.
谁知道?
我已经在一个项目上工作了一段时间,它有一个内置的HTTP服务器,它运行在端口8080上.用户被告知通过例如http://192.168.1.4:8080/访问设备- 效果很好.最近我意识到应用程序可以使用端口80来消除对":8080"的需要,但是如果我尝试将端口设置为80,则会因"常规CFSocket错误"而崩溃.
有关如何在应用程序上为Web服务器启用端口80的任何想法?
以下是一些屏幕截图:
首先 - 在iPad上,应用程序显示您可以访问它的URL.
iPad http://enrogue.com/port80/ipad.jpg
第二 - Firefox,IP:
FF by IP http://enrogue.com/port80/firefox_byip.png
以上是来自商店的真实应用程序,它不是越狱魔法或任何东西.我知道端口<1024是为UNIX系统上的管理员保留的,所以上面的应用程序显然正在做一些特定的事情来访问端口.
最近我意识到我需要为init方法添加一个参数,用于我所拥有的辅助类.辅助类处理警报视图,因此它在init中已经有一堆参数,这些参数被查看,调整,然后发送到警报视图.
由于我在不同的地方使用这种方法,我不想冒险崩溃(错过其中一个地方并在客户手中获得'无法识别的选择器')所以我决定添加第二个init方法.
即
- (id)initWithA:B:C:D:
Run Code Online (Sandbox Code Playgroud)
和
- (id)initWithA:B:C:foo:D:
Run Code Online (Sandbox Code Playgroud)
现在我只是简单地将第一个实现粘贴到foo中:1,但理想情况下,第一个调用是第二个,即
- (id)initWithA:a B:b C:c D:d
{
return [self initWithA:a B:b C:c foo:nil D:d];
}
Run Code Online (Sandbox Code Playgroud)
但我不确定这是否可以接受.代码似乎工作正常.
在我正在研究的iPad项目中,我有一个UIWebView
应用程序内部显示.html文件,该文件链接到.css文件,即
<link rel="stylesheet" href="style.css" type="text/css">
Run Code Online (Sandbox Code Playgroud)
这些文件存储在iPad本地,但是从远程服务器获取.我注意到UIWebView
无限期地缓存.css文件,并且每当我更改它时都拒绝加载新文件.我曾经改变了文件的名称只是为了让它重置,但从长远来看这是不可接受的.
有没有办法防止缓存CSS文件UIWebView
?或者甚至更好,有没有办法说什么时候缓存,什么时候不?
我正在尝试以编程方式设置一个NSTextView
inNSScrollView
并且遇到了问题。
具体来说,我无法滚动文本视图;滚动视图似乎认为“这就是全部”。当您尝试向下滚动以查看其余内容(不释放)时,结果如下:
一旦你释放,滚动视图就会反弹回来,所以这不是图形故障;它只是在框架高度剪辑文本视图。
我尝试过使用Apple 的“Text In ScrollView”文档进行试验,并且我已经尝试过setVerticallyResizable:
等等。
编码:
- (void)configureValueTextView
{
NSScrollView *vfContainer = [[NSScrollView alloc] initWithFrame:(NSRect){0,0,50,50}];
vfContainer.hasVerticalScroller = YES;
vfContainer.hasHorizontalScroller = NO;
vfContainer.translatesAutoresizingMaskIntoConstraints = NO;
_valueFieldContainer = vfContainer;
vfContainer.borderType = NSLineBorder;
NSTextView *valueField = _valueField = [[NSTextView alloc] initWithFrame:(NSRect){0,0,vfContainer.contentSize}];
valueField.delegate = self;
valueField.minSize = (NSSize){0,0};
valueField.maxSize = (NSSize){FLT_MAX, FLT_MAX};
[valueField setVerticallyResizable:YES];
[valueField setHorizontallyResizable:YES];
valueField.translatesAutoresizingMaskIntoConstraints = NO;
valueField.string = _value ? _value : @"";
valueField.editable = YES;
valueField.textContainer.containerSize = (NSSize) { vfContainer.contentSize.width, …
Run Code Online (Sandbox Code Playgroud) 更新:此泄漏已解决.如果您遇到类似的泄漏,并且您的应用程序是多线程的,那么您最有可能从后台线程进行UIKit调用; 利用例如[NSThread performSelectorOnMainThread:]
将UIKit呼叫路由到主线程,这是 允许它们的唯一地方.
我最近在我目前的项目上运行Leaks以发现泄漏,并且我一直在遇到这些"泄漏",据我所知,这些泄漏并非真正泄漏.根据Leaks的说法,以下代码直接来自项目,有两个漏洞:
- (NSArray *)areaForIndex:(int)index
{
NSMutableArray *a = [NSMutableArray arrayWithArray:
[world retrieveNeighborsForIndex:index]]; // leak 1
[a insertObject:[references objectAtIndex:index] atIndex:0];
return [NSArray arrayWithArray:a]; // leak 2
}
Run Code Online (Sandbox Code Playgroud)
如果我将第一行更改为:泄漏1消失:(参见更新2-3)
如果我将最后一行更改为:泄漏2消失:
return a;
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不能用泄漏1做到这一点,因为我正在将一个不可变数组转换为可变数组.不过,无论如何,arrayWithArray应该是自动释放的,所以从我所知道的,它不应泄漏任何东西.任何想法为什么会这样?
更新:我在设备和模拟器上都测试了这个.两者都有泄漏.但是,在模拟器上,我得到了一些关于此泄漏的其他信息:
泄漏的历史如下:
# | Category | Event Type | Timestamp | RefCt | Address | Size | Responsible Library | Responsible Caller
--+----------+-------------+
0 | CFArray | Malloc | 00:09.598 | 1 | 0x474f6d0 | 48 | asynchro | -[muddyGrid areaForIndex:] …
Run Code Online (Sandbox Code Playgroud) 我花了整整一个星期的时间来追踪和打击头部的内存泄漏,我在那个星期的另一端到达时有点茫然.必须有一个更好的方法来做到这一点,我能想到的所有,所以我认为是时候问这个相当沉重的主题了.
这篇文章结果相当巨大.对此表示歉意,尽管我认为在这种情况下,尽可能彻底地解释细节是有道理的.显然是这样,因为它为你提供了我所做的所有事情的全貌,以找到这个bugger,这很多.这个错误花了我大约三个10多个小时的日子来追踪......
当我打猎泄漏
当我捕获泄漏时,我倾向于分阶段进行,如果在早期阶段无法解决问题,我会更深入地升级到问题中.这些阶段以泄漏开始告诉我有一个问题.
在这种特殊情况下(这是一个例子;错误已经解决;我不是要求解决这个错误的答案,我正在寻找方法来改进我发现错误的过程),我发现了泄漏(两个,偶数)在一个相当大的多线程应用程序中,特别是包括我正在使用的3个左右的外部库(解压缩功能和http服务器).那么让我们看看我解决这个漏洞的过程.
阶段1:泄漏告诉我有泄漏
Foundation的NSPushAutoreleasePool泄漏了2个GeneralBlock-160,泄漏160个字节http://enrogue.com/so/leaks.png
嗯,这很有趣.由于我的应用程序是多线程的,我首先想到的是我忘了把它NSAutoreleasePool
放在某个地方,但在检查了所有正确的地方之后,事实并非如此.我看一下堆栈跟踪.
阶段2:堆栈跟踪
泄漏的堆栈跟踪http://enrogue.com/so/leaks_extended_detail.png
两者的GeneralBlock-160
泄漏具有相同的堆栈跟踪(其是奇数,因为我有它由"相同的回溯"分组,但无论如何),其开始于thread_assign_default
并在结束malloc
下_NSAPDataCreate
.在这两者之间,绝对没有任何与我的应用程序相关的内容.这些电话中没有一个是"我的".所以我做了一些谷歌搜索,以弄清楚这些可能用于什么.
首先,我们有许多方法显然与线程回调有关,例如进入NSThread调用的POSIX线程调用.
在这个(倒置的)堆栈跟踪中的#8-6,我们已经+[NSThread exit]
跟随pthread_exit
并且_pthread_exit
这很有趣,但根据我的经验,我无法确定它是否表明某些特定情况或者它是否仅仅是"事情如何".
之后我们有一个线程清理方法叫做_pthread_tsd_cleanup
- 无论"tsd"代表我不确定,但无论如何,我继续前进.
在#4-#3,我们有:
CA::Transaction::release_thread(void*)
CAPushAutoreleasePool
Run Code Online (Sandbox Code Playgroud)
有趣.我们在Core Animation
这里.那,我已经学到了很难的方法,意味着我可能正在UIKit
从后台线程进行调用,我绝不能这样做.最大的问题是在哪里,以及如何.虽然可能很容易说"你不应该UIKit
从你们的背景线索中打电话",但要知道究竟什么构成一个UIKit
电话并不容易.正如你在这种情况下所看到的那样,它远非显而易见.
然后#2-1变得太低,没有任何实际用途.我认为.
我仍然不知道哪里开始寻找内存泄漏.所以我做了唯一能想到的事情.
第3阶段:return
嘉豪
建议我们有一个看起来像这样的调用树:
App start
|
Some init
| \
A init B init - Other case - Fourth case
\ / \
Some …
Run Code Online (Sandbox Code Playgroud) 当我写东西时,一半的努力倾向于添加清晰简洁的调试输出,或者当需要调试时可以启用/禁用的功能.
调试功能的一个例子是下载器类,在这里我可以打开一个#define,让它"假装"下载文件,然后简单地把我送回去.这样我就可以测试用户下载文件时会发生什么,而不必等待网络每次都物理地抓取文件.这是很棒的功能,但#ifdefs的代码变得更加混乱.
我最终得到了一堆#define
像
// #define DEBUG_FOOMODULE_FOO
// #define DEBUG_BARMODULE_THINGAMAJIG
// ...
Run Code Online (Sandbox Code Playgroud)
对于我想看的东西没有注释.代码本身就像是
- (void)something
{
#ifdef DEBUG_FOOMODULE_FOO
DebugLog(@"something [x = %@]", x);
#endif
// ...
#ifdef DEBUG_FOOMODULE_MOO
// etc
}
Run Code Online (Sandbox Code Playgroud)
这对于编写/维护代码非常有用,但它对代码的外观没有任何作用.
人们如何编写毫不费力的即时长期调试"东西"呢?
注意:我不仅在这里谈论NSLogging ......我也在讨论像上面假装下载这样的东西.
我正在尝试使用以下代码将UIView缩小的屏幕截图缩小到缩略图大小,
UIGraphicsBeginImageContext(size);
[canvas.layer renderInContext:UIGraphicsGetCurrentContext()];
result = [UIGraphicsGetImageFromCurrentImageContext() retain];
UIGraphicsEndImageContext();
Run Code Online (Sandbox Code Playgroud)
上面的代码将简单地抓取原始未填充大小的视图的左上部分.
我确定我之前已经这样做了,但我无法让它发挥作用.谁知道这里有什么?
iphone ×9
objective-c ×5
ios4 ×3
xcode ×3
instruments ×2
ios ×2
memory-leaks ×2
caching ×1
cocoa ×1
code-cleanup ×1
coding-style ×1
css ×1
debugging ×1
file-format ×1
fileshare ×1
ipad ×1
itunes ×1
macos ×1
networking ×1
nsscrollview ×1
nstextview ×1
performance ×1
plist ×1
uiimage ×1
uitextfield ×1
uiwebview ×1
web-services ×1