您可以使用设备修改器(即~ipad)在Info.plist中提供设备特定的密钥,并指定特定于设备的启动图像(iPhone的Default.png和iPad的Default~ipad.png,例).Apple Docs中特别提到了这两件事,但他们并未说这适用于任何其他类型的文件.
我发现(非常偶然)这适用于通过加载.xib文件initWithNibName:bundle:.例如,我可以使用MyView.xib和MyView~ipad.xib,以及此代码:
MyViewController *viewController = [[MyViewController alloc]
initWithNibName:@"MyView" bundle:nil];
Run Code Online (Sandbox Code Playgroud)
...将在iPad上完全加载MyView~ipo.xib,在其他设备上加载MyView.xib.
那么,1)这是在某处记录的吗?我肯定找不到任何Apple文档.它确实比检查UI_USER_INTERFACE_IDIOM()并在任何地方硬编码两个不同的笔尖名称更容易,但如果没有记录,我有点不相信它.
并且,2)有谁知道这个iOS开始工作的版本是什么?我只在4.2中试过它,它在那里工作.一般的设备修饰符(即使是上面列出的文档内容)也只有4.0.
我有最新版本的Xcode.在我的一个项目中,我注意到iPhone的视图是新的iPhone 5屏幕尺寸.我喜欢它,但有没有办法切换回较小的屏幕尺寸?不是每个人都拥有iPhone 5.
我正在寻找iPhone的高分辨率计时代码,以便做一些性能计时.我想写这样的代码:
HighResolutionTimer* myTimer = [[HighResolutionTimer alloc]init];
[myTimer start];
[self doSomeLengthyOperation];
NSLog( @"doSomeLengthyOperation took %f seconds", [myTimer elapsedTime] );
Run Code Online (Sandbox Code Playgroud) 我们知道我们可以使用虚拟继承来解决钻石问题.
例如:
class Animal // base class
{
int weight;
public:
int getWeight() { return weight;};
};
class Tiger : public Animal { /* ... */ };
class Lion : public Animal { /* ... */ };
class Liger : public Tiger, public Lion { /* ... */ };
int main()
{
Liger lg ;
/*COMPILE ERROR, the code below will not get past
any C++ compiler */
int weight = lg.getWeight();
}
Run Code Online (Sandbox Code Playgroud)
当我们编译这段代码时,我们会得到一个模糊错误.现在我的问题是编译器内部如何检测这种模糊问题(钻石问题).
Objective-C没有命名空间,许多(例如CocoaDevCentral的Cocoa Style Guide)建议在您的类名前加上首字母,以避免命名空间冲突.
引用上面的链接:
Objective-C没有名称空间,因此在类名前加上首字母.这避免了"命名空间冲突",这是两个代码具有相同名称但执行不同操作的情况.
我认为这是有道理的.但老实说,在一个相对较小的应用程序(比如iPhone游戏)的背景下,这真的是一个问题吗?我应该真的将MyViewController重命名为ZPViewController吗?如果没有,命名空间冲突在什么时候真正成为一个问题呢?
我有一个Cocoa项目(Mac OS X应用程序),所有Objective-C.我从另一个项目中引入了一个C++类(我知道它可以工作),然后为它创建一个Objective-C包装器.ObjC包装器类使用.mm扩展名.但是,C++头文件包含#include标准C++头文件(<vector>例如),我得到了错误.
最小的例子如下所示.CppClass是C++类,CppWrapper是包装它的ObjC类.
// CppClass.h
#ifndef _CPP_CLASS_H_
#define _CPP_CLASS_H_
#include <vector>
class CppClass
{
public:
CppClass() {}
~CppClass() {}
private:
std::vector<int> my_ints;
};
#endif /* _CPP_CLASS_H_ */
// CppWrapper.h
#import <Foundation/Foundation.h>
#import "CppClass.h"
@interface CppWrapper : NSObject {
CppClass* myCppClass;
}
@end
// CppWrapper.mm
#import "CppWrapper.h"
@implementation CppWrapper
- (id)init
{
self = [super init];
if (self) {
myCppClass = new CppClass;
}
return self;
}
- (void)dealloc
{
delete myCppClass;
[super dealloc];
}
@end …Run Code Online (Sandbox Code Playgroud) 我在iPhone应用程序中有一段代码,它从UIView子类中删除所有子视图.它看起来像这样:
NSArray* subViews = self.subviews;
for( UIView *aView in subViews ) {
[aView removeFromSuperview];
}
Run Code Online (Sandbox Code Playgroud)
这很好用.事实上,在Mac OS X应用程序(来自NSView子类)中尝试几乎相同的东西之前,我从未真正考虑过它:
NSArray* subViews = [self subviews];
for( NSView *aView in subViews ) {
[aView removeFromSuperview];
}
Run Code Online (Sandbox Code Playgroud)
这完全不起作用.具体来说,在运行时,我得到这个:
*** Collection <NSCFArray: 0x1005208a0> was mutated while being enumerated.
Run Code Online (Sandbox Code Playgroud)
我最终这样做了:
NSArray* subViews = [[self subviews] copy];
for( NSView *aView in subViews ) {
[aView removeFromSuperview];
}
[subViews release];
Run Code Online (Sandbox Code Playgroud)
没关系.然而,令我烦恼的是,为什么它适用于iPhone呢?
子视图是一个复制属性:
@property(nonatomic,readonly,copy) NSArray *subviews;
Run Code Online (Sandbox Code Playgroud)
我的第一个想法是,当指定copy属性时,@ synthesize'd getters可能会返回一个副本. doc对于setter的复制语义很清楚,但似乎没有对getter说出任何一种方式(或者至少对我来说不明显).实际上,做了我自己的一些测试,这显然不是这种情况.哪个好,我认为返回副本会有问题,原因有几个.
所以问题是:上面的代码如何在iPhone上运行?NSView显然返回了一个指向实际子视图数组的指针,也许UIView不是.也许它只是UIView的一个实现细节,我不应该对此进行研究.
有人可以提供任何见解吗?
我已经阅读了整本Swift书,并观看了所有WWDC视频(我衷心推荐所有这些视频).我担心的一件事是数据封装.
考虑以下(完全做作的)示例:
class Stack<T>
{
var items : T[] = []
func push( newItem: T ) {
items.insert( newItem, atIndex: 0 )
}
func pop() -> T? {
if items.count == 0 {
return nil;
}
return items.removeAtIndex( 0 );
}
}
Run Code Online (Sandbox Code Playgroud)
此类实现堆栈,并使用Array实现它.问题是items(像Swift中的所有属性一样)是公共的,因此没有任何东西阻止任何人直接访问(甚至变异)它与公共API分开.作为一个蹩脚的老C++家伙,这让我非常脾气暴躁.
我看到有人抱怨缺乏访问修饰符,虽然我同意他们会直接解决这个问题(我听说有传言说他们可能会实施Soon(TM)),但我想知道一些数据隐藏策略会在他们缺席时出现.
我错过了什么,或者这只是语言中的遗漏?
我有一个Cocoa应用程序.在窗口的视图中,我放置了一个NSImageView.使用自动布局我添加了前导和尾随空格,使NSImageView锚定到视图(以及窗口).
NSImageView的缩放属性已设置为ScaleDown.
当我把窗户放大时,一切都按预期发生.图像在窗口中居中,不会向上扩展.
问题是当我把窗口缩小时.一切正常,直到我达到图像的大小.然后我不能让窗户变小.
换句话说,我只能使窗口像图像的大小一样小.我想要的 - 并且通过使用ScaleDown设置所期望的 - 是使图像缩小窗口.
我编写了一个NSTextView子类,它对文本本身进行频繁的编程修改(有点像IDE的代码格式化 - 例如自动插入紧密括号).
我最初的实现使用了NSTextView insertText:.这实际上看起来完全正常.但是在阅读NSTextView文档时(我有时会为了好玩),我在讨论部分注意到了insertText:
此方法是插入用户键入的文本的入口点,通常不适用于其他目的.最好通过直接对文本存储进行操作来对文本进行编程修改.
哦,我的坏,我想.因此,我尽职尽责地将所有insertText调用更改为对底层NSTextStorage(replaceCharactersInRange:withString:主要是)的调用.这似乎工作正常,直到我注意到它完全搞砸了Undo(当然,因为Undo是由NSTextView处理的,而不是NSTextStorage).
所以在我把文件存储器中的buncha撤销代码拖出来之前,我想知道我insertText:是不是Punk'd,真的不是那么糟糕?
是的,所以我的问题是:NSTextView的insertText:调用真的"不适合"编程修改NSTextView的文本,如果是的话,为什么呢?
cocoa ×4
iphone ×4
objective-c ×4
macos ×3
c++ ×2
autolayout ×1
cocoa-touch ×1
ios ×1
ios6 ×1
ipad ×1
iphone-5 ×1
namespaces ×1
nstextview ×1
nsview ×1
swift ×1
timer ×1
uiview ×1
virtual ×1
wrapper ×1
xcode4.5 ×1