我的问题如下:我有一个单例类型的对象(我正在使用ARC),在实现文件中有这个代码
+(id)sharedInstance
{
static DataManager *sharedInstance;
if (sharedInstance == nil) {
sharedInstance = [[DataManager alloc] init];
}
return sharedInstance;
}
+(NSManagedObjectContext *)getManagedContext
{
AppDelegate *applicationDelegate =(AppDelegate *)[[UIApplication sharedApplication] delegate];
return [applicationDelegate managedObjectContext];
}
+(void)saveContext:(NSManagedObjectContext *)context
{
NSError *error;
if (![context save:&error]) {
NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
}
}
#pragma mark - Data management methods
+(void)addPersonWithName:(NSString *)name andPicture:(UIImage *)picture
{
NSManagedObjectContext *context = [self getManagedContext]; //no problem here
//some code
[self saveContex:context]; // no known class method for selector …Run Code Online (Sandbox Code Playgroud) 我正在尝试保留对通过方法传递给我的类的块的引用,以便稍后调用.然而,我遇到了麻烦,保持对它的引用.
我认为,显而易见的方法是将它添加到ivar集合中,所有这些集合都应该保持对其内容的强烈引用.但是当我试图将它拉回来时,它是零.
代码非常简单:
typedef void (^DataControllerCallback)(id rslt);
@interface DataController : NSObject {
NSMutableArray* queue;
}
- (void) addBlock:(DataControllerCallback)callback;
- (void) functionToBeCalledLater;
@end
@implementation DataController
- (id) init {
self = [super init];
if (self != nil) {
queue = [NSMutableArray new];
}
return self;
}
- (void) addBlock:(DataControllerCallback)callback {
NSDictionary* toAdd = [NSDictionary dictionaryWithObjectsAndKeys:
[callback copy], @"callback",
@"some other data", @"data", nil];
[queue addObject:toAdd];
}
- (void) functionToBeCalledLater {
NSDictionary* dict = [queue lastObject];
NSLog(@"%@", [dict objectForKey:@"data"]; //works
DataControllerCallback callback …Run Code Online (Sandbox Code Playgroud) 在ARC,它创建一个内存泄漏到alloc成@property (strong)
// MyClass.h
@property (strong) NSString *myString;
// MyClass.m
@synthesize myString=_myString;
- (void)viewDidLoad
{
self.myString = [[NSString alloc] initWithFormat:@"Test %@", otherString];
}
Run Code Online (Sandbox Code Playgroud)
我知道在手动内存管理中,等效会造成泄漏
// MyClass.h
@property (retain) NSString *myString;
// MyClass.m
@synthesize myString=_myString;
- (void)viewDidLoad
{
self.myString = [[NSString alloc] initWithFormat:@"Test %@", otherString];
}
- (void)dealloc
{
[_myString release];
}
Run Code Online (Sandbox Code Playgroud)
ARC能否正确处理顶级示例?它是否优化了其中一个保留?或者也许在dealloc中发布两次?
我有一个包含49个源文件的项目,我正在尝试使用edit> refactor> convert to arc转换为ARC .我点击"预检",没有错误,目标编译.
Xcode通过"生成预览",编译所有49个源文件,然后在审阅更改列表中显示1(或2)文件.这是一个.h/.m文件.那个看似正确.我看到该列表上没有其他文件.
当我单击"保存"时,窗口关闭,项目尝试构建,但失败并显示错误:
Error in format of file: ...-arc.migrate/remap
Run Code Online (Sandbox Code Playgroud)
这些错误出现在所有文件中
如果我尝试构建项目,我会得到〜350个错误,说"保留,不允许在ARC中释放"......请帮忙!
如何将整个项目立即转换为ARC?
更新:多次清理项目并将部署目标更改为iPhone 5模拟器后,我能够在"保存更改"列表中查看所有文件.
我们今天有一些代码接受NSArray并将其作为参数列表传递给 - [NSString initWithFormat:arguments],我们试图让它与ARC一起工作.这是代码使用的
NSString* format = @"Item %s and Item %s"; // Retrieved elsewhere
NSArray* args = [NSArray arrayWithObjects:@"1", @"2", nil]; // Retrieved elsewhere
// http://cocoawithlove.com/2009/05/variable-argument-lists-in-cocoa.html
char* argsList = (char*) malloc(sizeof(NSString*) * args.count);
[args getObjects:(id*) argsList];
NSString* message = [[[NSString alloc] initWithFormat:format arguments:argsList] autorelease];
free(argsList);
Run Code Online (Sandbox Code Playgroud)
有关如何使ARC符合要求的任何建议?或者我们甚至愿意接受更好的方式.
我有一些代码必须保留为c ++,但我需要在这些c ++类中存储objective-c对象.当它们存储在这里时,它们不会被其他任何地方引用,所以我不能将它们从我的下面删除.在ARC之前,我只是在将它们放入c ++类之前保留它们,并在它们被删除时自动释放它们.一切都有罚款.
但是对于ARC,我不知道该怎么做.是否使c ++变量__unsafe_un得足够?似乎不是因为一旦obj-c代码不再使用那些对象它将被删除,或者我不理解__unsafe_unretained做了什么.我可以在ARC下调用CFRetain()和CFAutorelase()吗?
在ARC下处理这个问题的正确方法是什么?NSArray做了什么深入了解它所存储的对象?
我有一个非常简单的单元测试设置.我有一个具有委托属性的类:
@interface MyClass : NSObject
...
@property (nonatomic, weak) id<MyDelegateProtocol> connectionDelegate;
...
@end
Run Code Online (Sandbox Code Playgroud)
我在我的测试中设置了委托:
- (void)testMyMethod_WithDelegate {
id delegate = mockDelegateHelper(); // uses OCMock to create a mock object
[[delegate expect] someMethod];
myClassIvar.connectionDelegate = delegate;
[myClass someOtherMethod];
STAssertNoThrow([delegate verify], @"should have called someMethod on delegate.");
}
Run Code Online (Sandbox Code Playgroud)
但是代理实际上并没有设置在我的单元测试的第3行,所以#someMethod从未被调用过.当我改为
myClassIvar.connectionDelegate = delegate;
STAssertNotNil(myClassIvar.connectionDelegate, @"delegate should not be nil");
Run Code Online (Sandbox Code Playgroud)
它失败了.我正在使用ARC,所以我的预感是弱房产被解除分配.果然,它更改为strong使STAssertNotNil通.但是我不想与代表那样做,我不明白为什么这会有所作为.根据我的阅读,ARC中的所有本地参考文献都是strong,并STAssertNotNil(delegate)通过.当局部变量中的同一对象不是时,为什么我的弱委托属性为nil?
我正在使用ARC,并在循环中修改字符串时看到一些奇怪的行为.
在我的情况下,我使用NSXMLParser委托回调循环,但我看到使用演示项目和简单修改某些NSString对象的示例代码的相同的确切行为和症状.
您可以从GitHub下载演示项目,只需在主视图控制器的viewDidLoad方法中取消注释四个方法调用之一,即可测试不同的行为.
为简单起见,这是一个简单的循环,我已经陷入了一个空的单视图应用程序.我将此代码直接粘贴到viewDidLoad方法中.它在视图出现之前运行,因此屏幕为黑色,直到循环结束.
NSString *text;
for (NSInteger i = 0; i < 600000000; i++) {
NSString *newText = [text stringByAppendingString:@" Hello"];
if (text) {
text = newText;
}else{
text = @"";
}
}
Run Code Online (Sandbox Code Playgroud)
以下代码在循环完成之前还会保留内存:
NSString *text;
for (NSInteger i = 0; i < 600000000; i++) {
if (text) {
text = [text stringByAppendingString:@" Hello"];
}else{
text = @"";
}
}
Run Code Online (Sandbox Code Playgroud)
以下是这两个循环在Instruments中循环的方式,运行Allocations工具:

看到?逐渐稳定的内存使用,直到一大堆内存警告,然后应用程序自然死亡.
接下来,我尝试了一些不同的东西.我使用了一个实例NSMutableString,如下:
NSMutableString *text;
for (NSInteger i = …Run Code Online (Sandbox Code Playgroud) memory-management objective-c instruments nsstring automatic-ref-counting
我正在编写一个使用ARC的应用程序,目前似乎有一些内存泄漏.谷歌搜索我发现了一些关于如何使用Inspector的提示.在那里,我可以看到一些类的实例分配的大量,我也可以看到一些调用堆栈关于如何分配对象以及如何更改保留计数.
但似乎我看不到完整的调用堆栈,所以我不知道最终谁拥有该对象.在我看来,这个所有者不知何故不释放对象(或拥有可疑对象的对象).
任何人都可以给我一个关于找到分配对象的所有者的提示吗?
另请注意,对象未标记为"已泄露"但已分配.对我来说,似乎是对象被泄漏,因为分配了稳定的新对象.
有关如何最好地进行和发现可疑泄漏的任何进一步帮助表示赞赏.
在ARC管理下使用Delphi for iOS终止线程的正确方法是什么?
举个简单的例子:
TMyThread = class(TThread)
protected
procedure Execute; override;
public
destructor Destroy; override;
end;
TForm2 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
FThread: TMyThread;
public
end;
{ TMyThread }
destructor TMyThread.Destroy;
begin
ShowMessage('Destroy');
inherited Destroy;
end;
procedure TMyThread.Execute;
begin
Sleep(5000);
end;
{ TForm2 }
procedure TForm2.Button1Click(Sender: TObject);
begin
FThread := TMyThread.Create(TRUE);
FThread.FreeOnTerminate := TRUE;
FThread.Start;
end;
procedure TForm2.Button2Click(Sender: TObject);
begin
ShowMessage(FThread.RefCount.ToString);
end;
procedure TForm2.Button3Click(Sender: TObject);
begin
FThread …Run Code Online (Sandbox Code Playgroud) objective-c ×7
ios ×4
cocoa ×1
delphi ×1
delphi-xe4 ×1
instruments ×1
ios5 ×1
memory ×1
memory-leaks ×1
migrate ×1
nsstring ×1
singleton ×1
unit-testing ×1
xcode4.2 ×1